__proto__和prototype的区别延伸到原型链

4,464 阅读2分钟
原文链接: github.com

__proto__和prototype的区别延伸到原型链

先不说__proto__和prototype是个什么东西,只知道跟对象有关系就可以了。首先,我们先看一个例子:

const o = { name: 'zhangsan', age: 24 };
const oFun = function(){
    this.name = "lisi";
    this.age = 23;
}

__proto__和prototype的区别

从调试的控制台可以看出:

普通对象:\__proto__;
函数:\__proto__、prototype。

所以,要想比较这两者的区别,潜在的条件是必须 是在函数中。

那么,函数跟对象有什么关系呢?

在这里需要声明:除了字符串、数字、true、false、null和undefined之外,JavaScript的值都是对象(摘自大犀牛的《javascript 权威指南》),所以函数(function)也是对象的一种。

好,确定了这两点,那么接下来我们的主体就是函数对象了,主题是__proto__、prototype。

介绍一下prototype: __proto__和prototype的区别

大概意思就是说,prototype是为其他对象提供共享属性的对象。当构造函数创建对象时,这个对象引用构造函数的prototype属性,添加对象的prototype的属性继承共享原型的所有对象共享。(摘自ECM www.ecma-international.org/ecma-262/5.…)

所以,prototype可以共享对象的属性,那么图一的oFun的prototype是Object的构造函数。

再来看__proto__:

__proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象,他本质是一个内部属性,不是一个正式对外的api,由于浏览器的广泛支持,才加入了es6,__proto__调用的是Object.prototype.proto。(摘自阮一峰的《ES6标准入门》es6.ruanyifeng.com/#docs/objec…

从这里得出另一个区别:__proto__是es6加入的内部属性,不是正式对外的api

细致的看下图:

__proto__和prototype的区别 oFun的prototype指向的是Object的constructor,属性都是外部可以访问到的,共享的;oFunction的__proto__指向的是函数本身的一些属性和函数是隐式的,外部访问不到的。

最后,我们在上述的例子中加一段代码:

const oFun = function(){
    this.name = "lisi";
    this.age = 23;
}

const f1 = new oFun();
const f2 = new oFun();
f1.name = 'fff';

new 函数创建的对象的示例用两张的图来阐述:

__proto__和prototype的区别

__proto__和prototype的区别

这样结论就很明确了,可以总结为以下几点:

1.所有对象都有__proto__属性。

2.只有函数对象才有prototype属性。

3.protoype对象默认有两个属性:constructor 和 proto

4.实例对象的__proto__指向的是函数的protoype

5.函数对象的prototype属性是外部共享的,而__proto__是隐式的。

6.函数和Object的__proto__的顶端是null

参考: