- 对于我们这种学Java/C++这种强类型基于类的语言出身的程序员,JavaScript这种动态语言写起来简直爽的飞起,但是后期维护就成了火葬场,虽然在ES6中引入了Class关键字,但那只是语法糖,JavaScript 仍然是基于原型的
继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承
.接口继承只继承方法签名,而实现继承则继承实际的方法.由于js中方法没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支持实现继承,而且其 实现继承 主要是依靠原型链来实现的.
原型链
- 在 javaScript中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为 null为止(也就是不再有原型指向),组成这条链的最后一环。这种一级一级的链结构就称为原型链(prototypechain)
1.每一个函数都有一个prototype属性,这个属性指向函数的原型对象
2.每一个对象都有_proto_属性,这个属性指向该对象的原型
let student = function () {
this.a = 1;
this.b = 2;
}
let xiaoMing = new student();
student.prototype.b = 3;
student.prototype.c = 4;
console.log(xiaoMing.a); // 1
console.log(xiaoMing.b); // 2
//b是xiaoMing的属性,值为2,原型上也有一个‘b’,但不会被访问到
console.log(xiaoMing.c); // 4
继承方法
JavaScript 并没有其他基于类的语言所定义的“方法”。在 JavaScript 里,任何函数都可以添加到对象上作为对象的属性。函数的继承与其他的属性继承没有差别,包括上面的“属性遮蔽”(这种情况相当于其他语言的方法重写)。
当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。
var o = {
a: 2,
m: function(){
return this.a + 1;
}
};
console.log(o.m()); // 3
// 当调用 o.m 时,'this' 指向了 o.
var p = Object.create(o);
// p是一个继承自 o 的对象
p.a = 4; // 创建 p 的自身属性 'a'
console.log(p.m()); // 5
// 调用 p.m 时,'this' 指向了 p
// 又因为 p 继承了 o 的 m 函数
// 所以,此时的 'this.a' 即 p.a,就是 p 的自身属性 'a'