一、原型链
放张图片镇镇场
1、prototype:原型
每个函数都具有一个属性prototype,值为一个对象。这个属性其实是给构造函数准备的,其他的函数不使用这个属性的功能。
prototype属性用来保存构造函数中所有需要公用的方法,简化代码的书写。
function CreateObj (name, age) {
this.name = name;
this.age = age;
}
CreateObj.prototype.sayHi = function () {
console.log('这是sayHi方法');
};
var c1 = new CreateObj('jack', 18);
var c2 = new CreateObj('rose', 21);
c1.sayHi();
c2.sayHi();
console.log(c1.sayHi === c2.sayHi);
console.log(c1);
console.log(c2);
2、__proto__
属性
通过观察对象,我们发现对象具有__proto__
属性,是new给对象设置的。
console.log(CreateObj.prototype === c1.__proto__); // true
这个__proto__
与CreateObj.prototype又实际上是同一个对象
对象的属性访问方式:首先找自身,自身有,使用;自身没有,查找__proto__
属性,如果有,使用。
3、constructor:构造器
constructor是prototype的属性,但是不是给自己准备的,而是让创建的对象是用的。
constructor用来描述对象和构造函数之间关系的一种方式。
console.log(CreateObj.prototype.constructor); // 得到构造函数
使用constructor还可以进行对象的类型检测
console.log(arr.constructor === Array); // true
console.log(arr.constructor === Object); // false
4、prototype的第二种设置方式
使用新对象覆盖原有的原型对象,写法较为简单。但原始的constructor属性也不存在了,需要自己进行设置。
function CreateObj (name) {
this.name = name;
}
CreateObj.prototype = {
sayHi : function () {
console.log('这是sayHi');
},
constructor : CreateObj
};
var c1 = new CreateObj('jack');
console.log(c1.constructor);
c1.sayHi();
5、三者关系
实例对象:通过构造函数创建的对象。每个实例对象都具有一个__proto__属性,指向了构造函数的原型对象。
构造函数:用于创建实例对象使用的。每个构造函数都具有一个prototype,指向了原型对象。
原型对象:都具有一个属性constructor,指向构造函数。