开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情
在 ES6 之前,JS 没有类和继承的概念,JS 是通过原型来实现继承的
一、原型
当我们声明一个函数function func() {}
的时候,func
实际上就是一个构造函数,每个函数都有一个属性:原型 prototype
func.prototype 的结构如下:
{
constructor: func(),
_proto_: ...
}
在控制台查看:
-
prototype 是以 [[prototype]] 这种形式出现的,表示此属性是对象的内部属性,不能被直接访问。
-
constructor 属性,表示指向该原型实例的构造函数
-
proto 属性,指向构造方法的原型对象,每个实例对象都有一个_proto_ 属性
二、原型链
每个对象都有一个原型,原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链
- 每个对象的
__proto__
都是指向它的构造函数的原型对象prototype
的 - 原型链顶端是 Object.prototype
- 一切对象都是继承自
Object
对象,Object
对象直接继承null
function Fruits(name,color) {
this.name = name;
this.color = color;
}
var p = new Fruits("apple","red");
Fruits.prototype.address = "Hebei";
console.log(p.__proto__ === Fruits.prototype) // true
console.log(Fruits.prototype.constructor === Fruits) // true
console.log(p.constructor === Fruits) // true
打印 p ,可以看到如下结构:
原型链查找过程:
-
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有这个属性,就会去他的
__proto__隐式原型
上去找(即它的构造函数的 prototype) -
如果还找不到,就去原型的原型(
即构造函数的prototype的__proto__
)上去找,.... -
一直找到最顶层(
Object.prototype
)为止 -
如果还没有找到,则返回 undefined
三、 [ ] 的原型链是怎样的 ?
- [].proto 指向 Array.prototype
- Array.prototype.proto 指向 Object.prototype
- Object.protytype.proto 的最终指向为 null
四、判断原型的方法
- instanceof
- in —— 管是不是在原型上,只要存在就是true
- Object.hasOwnProperty —— 判断某个属性是否在自己上面(不是原型上,如果属性在原型上会返回 false)
具体实现可参考前文:手写系列 | instanceof 原理及实现