函数原型和原型链究竟是个啥?

  • A+
所属分类:前端

这篇文章旨在用最简单的语言告诉你什么是原型对象以及什么是原型链。

为啥说 null、undefined 和 函数搞特殊

所有的数据类型(除了 nullundefined)都有 contructor 构造函数(其实这么说并不准确,后面有讲原因),但只有 函数 才有 prototype 属性:

这下知道为啥别人说 nullundefined 是特殊的数据类型了吧!也知道为啥别人说函数是特殊的对象了是不是?这也是为啥有人说 函数是一等公民 的原因,正是因为函数具有 prototype 属性使它拥有了无限的扩展性。

prototype 指向一个包含 constructor 属性的对象。说白了,就是 prototype 是一个对象,具有 constructor 属性,也是一个对象。该 contructor 属性值为对象本身:

我怀疑 JS 作者当初只是想通过 prototype.constructor 来描述一个方法的构造函数就是它本身。而其它语言的构造函数,如 Java, 只是一个与类同名的函数。

__proto__prototype 的关系

__proto__ 其实是 ECMAScript 标准 [[Prototype]] 的代理实现,是各浏览器提供的,检查浏览器是否支持此属性可以使用 Object.getPrototypeOf({__proto__: null}) === null

__proto__ 指向对象的构造函数的 prototype

上面的描述并不准确

上面说所有的数据类型都有构造函数并不准确或者说是不够精细。当我们创建一个空对象的时候你会发现这个空对象并不 “空”:

既然是 “空” 对象,为什么还会有 constructor 属性呢?

嗯,这个时候再引入 __proto__ 应该会把事情搞明白。其实这里的 object.constructor 应该是 object.__proto__.constructor,所以 constructor 其实并不是内部属性。:

而前面说过 __proto__ 指向的是对象构造函数的 prototype,那么这里的 constructor 是不是就是其对象构造函数下的 prototype.constructor 呢?答案是:bingo

所以 __proto__ 的作用是,当访问一个对象的属性时,如果该属性不直接存在对象上,则会去其 __proto__ 所指向的对象里去找,如果不存在就会一直找下去,直到 __proto__ 值为 null

prototype 的作用又是什么呢?简单来说,就是共享属性和方法。

啥时候 new

new 关键字经常会被使用,但可是你知道什么时候才需要 new 吗?是的,很简单判断。如果你将要调用的属性或方法是属于调用对象的 prototype 的,那么在使用它之前你需要先实例化这个对象。

利用原型链模仿高级语言的面向对象

学完 JavaScript 中的原型和原型链后再去学 JavaScript 中的面向对象和设计模式必定会轻车熟路。由于篇幅有限,后面再细讲如何模仿面向对象语言和如何开发设计模式。


本文作者懒得画图,因为作者认为这个东西不太好用图去描述,一想到画图,作者就想去画堆和栈。等画出来估计几个小时就过去了。

ultravires

发表评论

您必须才能发表评论!