为什么要理解原型和原型链,因为有利于我们理解和实现 JS对象继承。
__
proto__
-
__proto__
是什么When a constructor creates an object, that object implicitly references the constructor’s prototype property for the purpose of resolving property references. -----------ES6 文档
JS 中创建出来的对象都会有一个隐式引用,它指向的是构造器的
prototype
。这个隐式引用就是对象内部[[prototype]],通常情况下我们是无法访问到这个属性的,但是可以通过浏览器实现的__proto__
属性去访问它,每一个对象都会有一个__proto__
属性。虽然可以通过__proto__
访问到[[prototype]],但是ECMAScript 不建议通过__proto__
去修改内部[[prototype]] 属性,因为这是个影响性能的操作。 __proto__
指向哪里
__proto__
是一个引用而且指向constructor 的prototype
prototype
-
prototype 是什么?
只有函数才会有prototype
属性。当你创建一个函数时,它的prototype
会初始化为一个"空对象" (里面含有一个constructor
属性,它是不可枚举属性,近似认为"空对象"),之后就可以往里面增加属性或方法。prototype
主要用于存储公用的方法和属性,然后等待实例的__proto__
来指向它。
原型链
-
空对象toString() 方法从何而来?
其实上面的代码,做了下面几件事:- 看看 obj 对象本身有没有 toString 属性。没有就走到下一步。
- 看看 obj.
__
proto__
对象有没有 toString 属性,发现 obj.__
proto__
有 toString 属性,于是找到了。所以 obj.toString 实际上就是第 2 步中找到的 obj.__
proto__
.toString。
------知乎专栏:什么是 JS 原型链?
由于
obj.__proto__
===Object.prototype
所以obj 还可以调用Object.prototype
中其它的属性。可是如果obj 调用的属性在Object.prototype
上也没有呢?那么它就会在Object.prototype.__proto__
中寻找,又Object.prototype.__proto__
等同于obj.__proto__.__proto__
。所以如果在obj.__proto__.__proto__
上也没有找到,他会继续在obj.__proto__.__proto__.__proto__
上寻找,直到他找到属性或者 .__proto__
为null 。如
obj.__proto__.__proto__. . . . . .
这样由.__proto__
组成的链条,就是原型链。 通过原型链,实例可以得到自身没有但原型链上存在的方法或属性。其实
instanceof
就是利用原型链的特点来工作的。比如判断obj 是否是Object 的实例(obj instanceof Object
),相当于判断obj.__proto__.__proto__. . .
是否等于Object.prototype
。 -
原型链的重点
__proto__
和prototype
之间的相互关系,构成了JS 的原型链。个人认为掌握原型链,必须记住下面三句话:- 某对象的
__
proto__
===== 它构造函数的prototype - Object.prototype.
__
proto__
===== null - Function.prototype.
__
proto__
===== Object.prototype
- 某对象的
-
Function.prototype 和Obect.prototype
Function
是所有函数的原型(Function.prototype
除外)。它是对象同时又是函数,所以它有__proto__
和prototype
属性。利用上面三句话的第一句某对象的
proto
===== 它构造函数的prototype
,可以得到:Function.__proto__
===Function.prototype
。而Object
、Number
、String
、Array
、Boolean
等构造函数情况同Function
相差不大,所以它们都是继承自Function
,它们的__proto__
会等于Function.prototype
。Function.prototype
继承自哪里?typeof Function.prototype //"function" Function.prototype instanceof Function //false Function.prototype.prototype //undefined
由上面可以得到:
Function.prototype
是一个没有prototype
属性的函数,它不是继承自Function
。Function.prototype instanceof Object //true Function.prototype.__protot__ === Object.prototype //true
得到
Function.prototype
是继承自Object 的。
Object.prototype
继承自哪里?typeof Object.prototype //"object" Object.prototype instanceof Object //false Object.prototype.__proto__ === null
得出
Object.prototype
是一个对象,但他不是继承自Object
对象,也不是继承自null,它是对象继承的最顶端。 总结
- 原型图
链接
1、从proto和prototype来深入理解JS对象和原型链
2、js中proto和prototype的区别和关系? ---苏墨橘的回答
3、什么是 JS 原型链?