走一遍流程图,了解 [[prototype]]、__proto__、prototype究竟是什么

大纲

[[prototype]]、proto、prototype究竟是什么。遍走这个经典的流程图,遍解释它们的含义。

写在最前面

原型链的尽头(root)是Object.prototype。所有对象均从Object.prototype继承属性。

prototype

每个函数都有prototype属性(图一:1),也只有函数才有prototype属性。除了 Function.prototype.bind(),该属性指向原型。

var obj = {name: 'aaa'};
obj.prototype; // undefined
复制代码

Foo是一个函数,所有的函数默认都会拥有一个prototype,值是一个有constructor属性的对象,这个属性关联的是函数Foo(图一:2)。

prototype.constructor
function Foo() { 
    ...
}
Foo.prototype.constructor === Foo; // true
复制代码

constructor使我们能以构造函数的形式去new这个函数,JS就会创建该构造函数的实例并给所创建函数(图里是f1)一个内部的__proto__。(图二:4)

function Person() {
    ...
};
var person1 = new Person();
console.log(person1.constructor === Person); // true
复制代码

person1作为Person的实例,没有.constructor属性。是通过__proto__原型链在原型Person.prtototype上面找到的。

new 的过程
  • 新生成了一个对象
  • 链接到原型
  • 绑定 this
  • 返回新对象
proto
  1. 每个对象都有__proto__,指向构造函数的prototype,继承prototype的所有属性和方法。对象可以通过__proto__来寻找不属于该对象的属性,__proto__将对象连接起来组成了原型链。
function Foo() {// 原型属性

};
Foo.prototype.name = "Yuan";

var f1 = new Foo();

console.log(f1.name);// 'Yuan';

f1.name = 'Y';

console.log(f1.name);// Y
复制代码

上面代码中在实例属性和原型属性都有一个名为name的属性,但是最后输出来的是实例属性上的值。

当我们读取一个属性的时候,如果在实例属性上找到了,就读取它,不会管原型属性上是否还有相同的属性,这其实就是属性屏蔽即当实例属性和原型属性拥有相同名字的时候,实例属性会屏蔽原型属性,记住只是屏蔽,不会修改,原型属性那个值还在。

  1. __proto__这个属性其实指向了[[prototype]],但是[[prototype]]是内部属性,我们并不能访问到,所以使用__proto__来访问。

  1. Foo的[[Prototype]]是Function.prototype。(图一:3)

  2. 虽然无法访问[[prototype]],但还是有方法去验证它的存在的。

  • Object.getPrototypeOf这个方法返回[[Prototype]]的值,可以获取到一个对象的原型
Person.prototype.isPrototypeOf(person1) // true
Person.prototype.isPrototypeOf(person2) // true
复制代码
Object.prototype

Object.prototype是原型链的顶端,所有对象从它继承了包括toString等等方法和属性。Object.prototype的__proto__指向nullObject.prototype没有原型(5)

(f1)函数对象也是对象,所以也有proto属性,连接它的原型。原型对象Foo.prototype的原型就是Object.prototype。(6)

但Object本身是构造函数有constructor属性(7),继承了Function.prototype,是Function的实例。(8)

Function.prototype和Function.__proto__为同一对象。而Function也是对象,继承了Object.prototype。Function.prototype直接继承root(Object.prototype)。(9)

Object instanceof Function // true
Function instanceof Object // true
复制代码

那么是先有了Object还是先有了Function?

ES规范:

Function本身就是函数,Function.__proto__是标准的内置对象Function.prototype

Function.prototype.__proto__是标准的内置对象Object.prototype

最后总结:先有Object.prototype(原型链顶端),Function.prototype继承Object.prototype而产生,最后,Function和Object和其它构造函数继承Function.prototype而产生。

参考资料:github.com/KieSun/Blog…

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值