JS继承设计的缘由
看了阮一峰老师文章,总结了如下的几点:
- JS是基于面向对象的语言,需要一种机制,实现对象之间的关联
- 借鉴面向类的语言中
constructor
构造函数的思想,和new
关键字 - 解决数据共享的问题,引入
prototype
继承的实现方式
继承FAQ
__proto__ 与 prototype
__proto__(隐式原型)与prototype(显式原型)
首先,让我们明确以下的三点
显式原型:每一个
函数
在创建之后,都会拥有一个名为prototype
的属性,这个属性指向函数的原型对象
隐式原型:JavaScript中任意对象都有一个内置属性
[[prototype]]
,在ES5
之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__
来访问。ES5中有了对于这个内置属性标准的Get方法Object.getPrototypeOf()
.- 隐式原型指向
constructor
的prototype
两者的作用:
- 显式原型的作用:用来实现基于原型的继承与属性的共享。
- 隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。
几点注意的地方:
- 通过
Function.prototype.bind
方法构造出来的函数是个例外,它没有prototype
属性 Object.prototype
这个对象是个例外,它的__proto__
值为null
- 只有函数才有
prototype
属性,这个属性值为一个object
对象
实例对象时没有这个属性的,实例对象通过__proto__
这个内部属性([[prototype]])来串起一个原型链的,通过这个原型链可以查找属性,方法
通过new操作符初始化一个构造函数对象的时候就会构建出一个实例对象,访问实例的constructor
其实是访问实例的__proto__
上的constructor
对象,该对象指向的是prototype
属性所在函数的指针。
关于Object.getPrototypeOf
:
Object.getPrototypeOf
与__proto__
的指向是一直的, prototype
是用于类型的,而 Object.getPrototypeOf()
是用于实例的(instances
)
当执行以下的简单的代码时:
Bob.someProp
它会检查是否存在 someProp
属性。如果没有,它会查找 Object.getPrototypeOf(o).someProp
,如果仍旧没有,它会继续查找 Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp
,一直查找下去,直到它找到这个属性 或者 Object.getPrototypeOf()
返回 null
注意:Object.getPrototypeOf(Object.prototype) 为null