目的
- 理解什么是原型对象
- 描述和理解__proto__、原型和构造函数之间的关系。
- 在原型对象上添加方法和属性,以编写更有效的代码
- 解释向原型添加方法和属性与构造函数之间的区别
- 通过prototype对象实现JavaScript中的继承
关键字new
我们之前使用了new关键字来从构造函数中创建对象——让我们回顾一下它的作用
- 创建一个空对象
- 将“this”的值赋给该对象
- 在函数最后添加“return this”
- 在这些新对象和构造函数的原型属性上创建一个连接(传说中的原型链) 现在我们专注于第四点,看看原型链到底是什么
一个图例
图例说明
- 每一个构造函数都有一个叫做prototype(原型)的属性,原型属性的值时一个对象
- 这个原型对象有一个叫做constructor的属性,它指向这个构造函数
- 每次当一个对象用new关键字创建的时候,会产生一个"proto" (原型链),它会把这个对象和构造函数的原型属性连接
- 每一个构造函数都有一个叫做原型的属性,原型属性的值时一个对象
代码说明
function Person(name,age){ this.name = name; this.age = age } var p1 = new Person("p1",12) var p2 = new Person("p2",22) p1.__proto__ === Person.prototype // true p2.__proto__ === Person.prototype // true Person.prototype.constructor === Person; // true复制代码
原型
原型的位置:原型被构造函数创建,由所有被该构造函数创建的对象共享!!
// 构造函数 function Person(name){ this.name = name; } // 由Person构造函数创建一个对象 var p1 = new Person("小美") var p2 = new Person("小李") Person.prototype.isInstructor = true; p1.isInstructor; //true p2.isInstructor; //true // 我们为什么可以访问原型的属性 // __proto__!!复制代码
原型链
JavaScript 中如何找到方法和属性? 图例说明
重构代码
既然我们知道由同一个构造函数创建的对象有一个共享的原型,让我们重构一些代码:
function Person(name) { this.name = name } Person.prototype.sayHi = function() { return "Hi " + this.name } var p1 = new Person("dd") p1.sayHi() // Hi dd复制代码
自我测试
- 创建一个构造函数Vehicle:从这个构造函数创建的每个对象都应该有一个make、model和year属性。每个对象还应该有一个名为isRunning的属性,该属性应该设置为false
- 从Vehicle构造函数创建的每个对象都应该具有一个名为turnOn的函数,该函数将isRunning属性更改为true
- 从Vehicle构造函数中创建的每个对象都应该有一个名为turnOff的函数,它将isRunning属性更改为false。
- 从Vehicle构造函数创建的每个对象都应该有一个名为honk的方法,该方法只在isRunning属性为true时返回字符串“beep”
测试代码
function Vehicle(make, model,year) { this.make = make this.model = model this.year = year this.isRunning = false } Vehicle.prototype.turnOn = function () { this.isRunning = true } Vehicle.prototype.turnOff = function () { this.isRunning = false } Vehicle.prototype.honk = function () { if (this.isRunning === true) { return 'beep' } }复制代码