proto 和 prototype 是一个老生常谈的话题,也是作为一个前端开发人员必须搞懂的问题,且不应该有任何的折扣,这是通往高级前端开发的必经之路和必备技能。虽然实际开发中用的并不多,但是当你学习一些新的js框架乃至自己封装一些高性能的组件时是及奇有用的。
网上的相关资料很多,讲解也是多种多样,但是至今都没有看到一篇自己满意的文章,于是在翻阅众多资料以及相关书籍之后,作者我一鼓作气,撸起袖子——就是干。
在正式进行讲解时,各位看官务必弄清楚以下两个问题。
看到这里我知道你开始吐槽了,和网上看到的大部分一样,然后表示一脸懵逼
别急,接下来我会为你一一剖析每一个过程
为了配合讲解,先上一段代码,边思考边往下看(程序猿的世界里最讲道理的就是这东西了):
Function.prototype.b = 666; // Funciton 中添加属性b
Object.prototype.a = 8888; // Object 中添加属性a
function foo() {
this.d = 999;
}
// 构造函数创建的实例
var f1 = new foo(); // 实例 object
console.log(f1.a); // 8888
console.log(f1.b); // undefined
console.log(foo.a); // 8888
console.log(foo.b); // 666
var o1 = new Object();
console.log(o1.a); // 8888
console.log(o1.b); // undefined
console.log(Object.a) // 8888
console.log(Object.b) // 666
var f1 = new foo(); // 实例 object
console.log(f1.a); // 8888
console.log(f1.b); // undefined
通过 new 构造出来的实例 f1 的 proto 指向了构造函数【foo】的原型, foo 的 proto 直接指向了 Object.prototype ,我们刚才手动在 Object 的 prototype 上添加了属性a。Object.prototype.a = 8888; 所以有了如下结果:
console.log(f1.a); // 8888
有因为 new 出来的 f1 仅仅是 Object 的实例,最终只能继承 Object原型上的属性,所以对于没有的属性 b 自然就是 undefined
console.log(f1.b); // undefined
到此我们了解了构造函数实例、构造函数、以及构造函数 prototype 之间的关系,接下来,我们在身下的部分,如图所示:
console.log(foo.a); // 8888
console.log(foo.b); // 666
有图中标号为1的线,我们知道 foo 的 proto 指向 Function.prototype 所以就有了
Function.prototype.b = 666; // Funciton 中添加属性b
console.log(foo.b); // 666
根据图中的4号线的指向,Function.prototype 的 proto 指向 Object.prototype 所以就有了
Function.prototype.b = 666; // Funciton 中添加属性b
console.log(foo.a); // 8888
也就是说 foo 同时继承了 Function.prototype 和 Object.prototype 的属性
var o1 = new Object();
console.log(o1.a); // 8888
console.log(o1.b); // undefined
o1 为 Object 的实例, Object 的原型指向 Object.prototype,所以o1 自然而然的继承了 Object.prototype 的属性
整个图中最难以理解的部分就是 Object 和 Function.prototype 的关系了,为啥 对象又函数扯上关系了,也不知道当初祖师爷是怎么想的,既然如此,路一行代码看看就知道了。
console.log(Object.a) // 8888
console.log(Object.b) // 666
果然不出所料,Object 同时继承了 Object.prototype 和 Function.prototype 的属性
一开始,我们的代码就用代码展示了 这个经典的图中的 proto 和 prototype 之间的关系,而后有简单的结合代码做了展示,相信各位也已经看懂了,也了解 函数的实例、构造函数的实例、构造函数、函数以及对象之间的关系。在这里作者我需要向各位强调以下必须注意的知识点
记住以下几点,我想足够纵横 proto 和 prototype 的关系,彻彻底底的弄明白原型链之间的工种关系。测地弄明白这张图和这几行代码个人认为足够了,如果各位看官还是觉得有点吃力,好好看看 《高级程序设计第三版》PDF请自行异步这里下载 的第六章关于原型链的讲解,看完之后在回过头来看看这图,相信一定会荒原大悟。
欢迎各位看官的批评和指正,共同学习和成长
希望该文章对您有帮助,你的 支持和鼓励会是我持续的动力