prototype | 原型
example function
// 第一步 创建构造函数
function Person(name) {
this.name = name;
this.sayName = function() {
console.log(this.name);
}
}
// 第二步 创建实例
var p1 = new Person('person')
下面(
prototype、__proto__、constructor)以此例子进行解释
prototype
它是函数所独有, 从一个函数(
Person)指向一个对象(prototype),它的含义是函数的原型对象任何函数在创建的时候,其实会默认同时创建该函数的
prototype对象。prototype会自动获得constructor和__proto__,这两个属性都是用来储存指针。constructor指向函数本身Person.prototype.constructor === Person;__proto__指向内置对象(个人感觉非常重要的一点,下面详细解释)Person.prototype.__proto__ === Object.prototype;
Person.prototype 结构
console.dir( Person.prototype );
// 输出
{ /*Person.prototype*/
// 指向函数本身
constructor: ƒ Person(),
__proto__: { /*Object.prototype*/
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
__proto__
ES标准定义中的名字是
[[Prototype]], 谷歌浏览器的实现就是将其命名为__proto__(名字有所差异,功能是一样)。它是对象所独有,指向该对象(
p1)的构造函数的原型对象(Person.prototype)。p1.__proto__ === Person.prototype;原型对象本身是一个普通对象,而普通对象的构造函数都是
ObjectPerson.prototype.__proto__ === Object.prototype;函数也是一种特殊对象,所以函数也拥有
__proto__,而且都统一指向Function.prototype,包括Function本身。Person.__proto__ === Function.prototype; Object.__proto__ === Function.prototype; /**Function 比较特殊,__proto__ 向上访问时可以回到本身*/ Function.__proto__ === Function.prototype;Object的原型对象也有__proto__属性,比较特殊,指向null,所以null是原型链的顶端Object.prototype.__proto__ === null;它的作用就是当访问一个对象(
p)的属性时,如果该对象内部不存在这个属性,那么就会去p1.__proto__所指向的那个对象(可以理解为父对象Person.prototype)里找,如果父对象也不存在这个属性,则继续往父对象(Person.prototype.__proto__)...如果还没找到,则继续往上找…直到原型链顶端null到此结束。通过
__proto__属性来连接对象直到null的一条链即为我们所谓的原型链。p1.__proto__ === Person.prototype; Person.prototype.__proto__ === Object.prototype; Object.prototype.__proto__ === null;
constructor
单从
constructor这个属性来讲,只有prototype对象才有。每个函数在创建的时候,JS会同时创建一个该函数对应的prototype对象它是对象所独有,从一个对象指向一个函数, 含义就是指向该对象(
p1) 的构造函数(Person)。p1.constructor === Person; /**访问流程*/ /**先通过 __proto__ 找到对应 prototype */ p1.__proto__ --> Person.prototype; /**再从 prototype 里找 constructor ,要是没用会继续通过 __proto__ 向上查询*/ Person.prototype.constructor === Person; /**与上面 p1.constructor === Person 等价*/所有函数和对象最终都是由
Function构造函数得来,所以constructor属性的终点就是Function这个函数。Person.constructor === Function; Object.constructor === Function; /**因为上面 __proto__ 第四点提到 Function 的特殊性,所以出现下面例子*/ Function.constructor === Function;