原型和原型链
原型
JavaScript 这门语言没有类的概念,所以 JavaScript 并非是基于类的继承,而是基于原型的继承
JavaScript 摒弃类转而使用原型作为实现继承的基础,是因为基于原型的继承相比基于类的继承上在概念上更为简单。首先我们明确一点,类存在的目的是为了实例化对象,而 JavaScript 可以直接通过对象字面量语法轻松的创建对象。
prototype 属性。 所有通过函数 new 出来的对象,这个对象都有一个 __proto__ 指向这个函数的 prototype。__proto__ 中找。1. prototype [显式原型]
prototype 是一个显式的原型属性,只有函数才拥有该属性。
每一个函数在创建之后都会拥有一个名为 prototype 的属性,这个属性指向函数的原型对象。( 通过 Function.prototype.bind 方法构造出来的函数是个例外,它没有 prototype 属性 )。
protptype 是一个指针,指向的是一个对象。比如 Array.ptototype 指向的就是 Array 这个函数的原型对象。
函数的原型对象中有constructor和_proto_两个特别的属性
constructor属性指向的就是该函数本身

2. __proto__[隐式原型]
__proto__ 指向了创建该对象的构造函数的显式原型

打印_proto_属性,发现其指向的是object.prototype,为什么?
因为这个 __proto__.constructor 指向的是 Object。
而我们知道:一个函数的原型对象的构造函数是这个函数本身。
所以这个 __proto__.constructor 指向的是 Object.prototype.constructor。
进而 __proto__ 指向的是 Object.prototype。

至于为什么是指向 Object? 因为所有的引用类型默认都是继承 Object 。
作用:
- 显式原型:用来实现基于原型的继承与属性的共享。
2. 隐式原型:构成原型链,同样用于实现基于原型的继承。 举个例子,当我们使用 noWork 这个对象中的 toString() 属性时,在noWork 中找不到,就会沿着 __proto__ 依次查找
3. new 操作符
当我们使用 new 操作符时,生成的实例对象拥有了 __proto__属性。即在 new 的过程中,新对象被添加了 __proto__ 并且链接到构造函数的原型上。
new 的过程
- 新生成了一个对象,继承对象类的原型,
- 执行对象类的构造函数,同时该实例的属性和方法被this引用,即this指向新构造的实例
- 新创建的对象由this引用,隐式返回this

我们知道所有对象都可以通过原型链最终找到 Object.prototype ,虽然 Object.prototype 也是一个对象,但是这个对象却不是 Object 创造的,而是引擎自己创建了 Object.prototype 。 所以可以这样说:
所有实例都是对象,但是对象不一定都是实例。
接下来我们来看 Function.prototype 这个特殊的对象:
打印这个对象,会发现这个对象其实是一个函数。我们知道函数都是通过 new Function() 生成的,难道 Function.prototype 也是通过 new Function() 产生的吗?这个函数也是引擎自己创建的。
首先引擎创建了
Object.prototype,然后创建了Function.prototype,并且通过__proto__将两者联系了起来。
这就是为什么 Function.prototype.bind() 没有 prototype 属性。因为 Function.prototype 是引擎创建出来的对象,引擎认为不需要给这个对象添加 prototype 属性。
原型及及原型链使用参考: http://www.cnblogs.com/TomXu/archive/2012/01/05/2305453.html

浙公网安备 33010602011771号