C4:继承

原型

Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. By definition, null has no prototype, and acts as the final link in this prototype chain. --- MDN

当咱们在一个obj对象上查找是否具备某个属性的时候,这个过程是这样的:
1.如今obj 对象中查找是否有该属性,若是有,查找终止。(也就是说若是obj对象上面和它的原型上又一个同名属性,那么对象上面的属性优先。)
2.若是没有,则查看当前obj是否具备__proto__。这个__proto__就是obj原型的引用。若是obj对象没有原型,那么查找终止。
3.若是obj有原型,就查找obj的原型上是否有这个属性。若是有,查找终止。返回这个属性。
4.若是obj的原型上没有这个属性,则查看obj的原型是否有原型。若是没有,则查找终止。
5.若是obj的原型上上面有它本身的原型,那么继续在obj的原型的原型上继续查找。函数

几乎每个js对象都有原型,可是有个例外。性能

let a = Obeject.crate(null)
let b = {}

当Object.create()传入null的时候, 返回一个真正的空对象a。这个对象不一样于b,a对象上什么都没有,可是b对象上还有一个__proto__指向Object.prototype。this

__proto__和prototype

function Man(name){
    this.name = name
}
Man.prototype.setName = function(name){
    this.name = name
}
let a = new Man("lee")
console.log(a)

输出以下:spa

clipboard.png

实例化的对象a中 有两个属性一个是name,还有一个就是它的原型__proto__。而这个__proto__是指向a 这个对象的构造函数 (a.__proto__.constructor 就是a这个对象的构造函数,也就是Man这个函数。) 的原型的。而且,修改对象的__proto__是不推荐的作法,对于性能的影响可能有时候咱们不能不重视。而在Man的这个函数的prototype上面咱们定义了一个setName的属性。
因此按照上面的查找流程,咱们在a对象的原型上找到了setName属性。prototype

如何继承

let animal = {
    weight:20,
    setWeight:function(weight){
        this.weight = weight
    }
}

function Cat(name){
    this.name = name
}

cat.prototype = animal

如上,只需简单将函数的prototype指向一个对象,就完成了对这个的对象的继承。如今全部经过new Cat()建立的对象都共享这个animal对象里面的属性。
这一点和直接使用Object.create()函数的继承方式很像。code

另一种继承方式,也是比较受开发者承认,相似于下面这种:对象

function Animal(weight){
    this.weight = weight
}
Animal.prototype.setWeight = function(weight){
    this.weight = weight
}
function Cat(name,weight){
    Animal.call(this,weight)
    this.name = name
}
//同时,咱们别忘了,将Cat的prototype设为Animal的prototype,这样就完成了对Animal的继承。
Cat.prototype = Object.create(Animal.prototype)
Cat.prototype.constructor = Cat

ES6 中出现了类的语法糖,咱们写继承就更简便了。继承

最后附上一张原型链的解析图:ip

clipboard.png

相关文章
相关标签/搜索