一坑未填,又起一坑
前记:尽管es6已经实现了class,但是原型链也伴随着我不少时间了,自己捋顺捋顺。
一个自定义的构造函数
第一次写一个JavaScript的类长这样:
var animals = function(name, sound) {
this.name = name;
this.sound = sound;
}
animals.prototype.getName = function() {
return this.name;
}
animals.prototype.setName = function(name) {
this.name = name
return this.name
}
animals.prototype.isSame = function(obj) {
if(this.sound === obj.sound) {
return true;
} else {
return false;
}
}
var dogJack = new animals("dogJack", "wang");
var catLucy = new animals("catLucy", "miao");
var dogKitty = new animals("dogKitty", "wang");
console.log(dogJack.isSame(catLucy)); // false
console.log(dogJack.isSame(dogKitty)); //true
在JavaScript权威指南(es5)里面的几种实现类的方法里选择了我看来比较类C++的一种写法,自定义一个构造函数,然后new出来一个实例,通过这种方法new出来的对象全都继承自同一对象,他们的原型都是构造函数的prototype。
调用内置的构造函数
当我们:
var dogLuccy = new Object({name:"dogLuccy",sound:"wang"});
dogLuccy.__proto__ = animals.prototype;
console.log(dogJack.isSame(dogLuccy)); // true
我们调用了内置的构造函数,dogLuccy 的new出来时继承了原型Object.prototype而后继承自animals.prototype的原型,而像var dogJack = new animals("dogJack", "wang");
是调用了自定义的构造函数,其原型是animals.prototype.
没有原型的对象Object.prototype
在JavaScript中大多数对象都有原型,但是Object.prototype是没有的,因为他是整个原型链的顶端,大家都继承自Object.prototype的原型。
当我们通过:
var c = Object.create()
var d = Object.create(Object.prototype)
创建一个对象时,c不继承任何属性和方法,d继承自Object.prototype,他和a,b是一样的。
es6中的class
如下
class Animal {constructor(){console.log("构造函数")}}
Animal === Animal.prototype.constructor // true
我们发现其实es6的class在es5中完全可以实现,它只是基于原型链的方式加了一层封装,有了class我们就可以像写c++的类一样写js的类了
总结,有个比喻很形象javascript在找一个对象是否有某个属性的时候就像顺藤摸瓜,一直到null,不再继承任何原型为止,尽管es6的class替我们加了一层封装,但是在javascript原型链是不能被忽略的,当原型链变得很长的时候,我们要在必要的时候结束原型链,给这个藤一个根部。