__proto__和prototype的区别延伸到原型链
先不说__proto__和prototype是个什么东西,只知道跟对象有关系就可以了。首先,我们先看一个例子:
const o = { name: 'zhangsan', age: 24 };
const oFun = function(){
this.name = "lisi";
this.age = 23;
}
从调试的控制台可以看出:
普通对象:\__proto__;
函数:\__proto__、prototype。
所以,要想比较这两者的区别,潜在的条件是必须 是在函数中。
那么,函数跟对象有什么关系呢?
在这里需要声明:除了字符串、数字、true、false、null和undefined之外,JavaScript的值都是对象(摘自大犀牛的《javascript 权威指南》),所以函数(function)也是对象的一种。
好,确定了这两点,那么接下来我们的主体就是函数对象了,主题是__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。
细致的看下图:
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 函数创建的对象的示例用两张的图来阐述:
这样结论就很明确了,可以总结为以下几点:
1.所有对象都有__proto__属性。
2.只有函数对象才有prototype属性。
3.protoype对象默认有两个属性:constructor 和 proto。
4.实例对象的__proto__指向的是函数的protoype
5.函数对象的prototype属性是外部共享的,而__proto__是隐式的。
6.函数和Object的__proto__的顶端是null
参考:
- 《ES6 标准入门》阮一峰 es6.ruanyifeng.com/#docs/objec…
- 《ECMA语言规范》 www.ecma-international.org/ecma-262/5.…
- 《JavaScript深入之从原型到原型链》github.com/mqyqingfeng…
- 《一张图理解prototype、proto和constructor的三角关系》www.cnblogs.com/xiaohuochai…