javascript面向对象编程学习(一)
javascript面向对象编程学习(二) —— 原型链继承javascript
利用call()
或apply()
方法,在子构造函数Child()
中,调用Person.call(this, name)
,加强子构造函数实例;实质等同于复制父实例给子函数。java
function Person(name) {
this.name = name;
this.names = ['大魔王','魔鬼', '恶魔'];
this.getName = function () {
console.log(this.name)
}
}
Person.prototype.say = function (){
console.log('my name is ' + this.name);
}
function Child(name, age){
// 继承Person
Person.call(this, name);
this.age = age;
}
var child = new Child('小魔王', 22);
var child1 = new Child('大魔王', 25);
console.log(child.names); // ["大魔王", "魔鬼", "恶魔"]
console.log(child1.names); // ["大魔王", "魔鬼", "恶魔"]
child.names.push('小魔王');
console.log(child.names); // ["大魔王", "魔鬼", "恶魔", "小魔王"]
console.log(child1.names); // ["大魔王", "魔鬼", "恶魔"]
console.log(child.name); // 小魔王
console.log(child.age); // 22
复制代码
call()
或apply()
方法来实现继承?首先,咱们要了解一下call的定义:调用一个对象的一个方法,以另外一个对象替换当前对象。
也就是说,当执行Person.call(this, name)
的时候,实质就是Person
的this
指向了Child
。
所以,实例child
也有了Person
的属性和方法了,也就实现了继承!编程
- 只能继承父类的实例属性和方法,不能继承原型属性/方法;
Person
的this
指向了Child
, 也就是说,Child
只是复制了Person
的属性和方法,原型链并无和它产生关系;child
实例的__proto__
仍是指向Child
。以下:![]()
- 没法实现构造函数的复用,每一个子类都有父类实例函数的副本,影响性能,代码会臃肿。
把原型链继承和构造函数继承的优势组合起来。使用构造函数继承实现对实例上的属性和和方法继承,使用原型链继承实现对原型上的属性和方法的继承。这样就能使在原型上定义的方法可以实现函数复用,而且没个实例也有本身的属性。app
function Person(name) {
this.name = name;
this.names = ['大魔王','魔鬼', '恶魔'];
}
Person.prototype.sayName = function (){
console.log('my name is:' + this.name);
}
function Child(name, age){
// 继承Person实例属性
Person.call(this,name);
this.age = age;
}
// 继承原型的属性和方法
Child.prototype = new Person();
Child.prototype.constructor = Child; // 由于原型链继承,会把constructor指向改变,因此要从新指回自身
Child.prototype.sayAge = function (){
console.log('my age is:' + this.age);
}
const child = new Child('小魔王', 22);
child.names.push('人');
child.sayName(); // my name is:小魔王
child.sayAge(); // my age is:22
console.log(child.names); // ["大魔王", "魔鬼", "恶魔", "人"]
const child2 = new Child('人', 28);
child2.sayName(); // my name is:人
child2.sayAge(); // my age is:28
console.log(child2.names); // ["大魔王", "魔鬼", "恶魔"]
复制代码
父类实例的属性和方法既存在于子类的实例中也存在于原型中。以下图:函数
想要弄清楚构造函数继承,要先弄明白
call()
和apply()
方法的定义和使用,要清楚this指向。
组合继承,当你弄清楚原型链继承和构造函数继承,而后再把二者结合去思考,就天然而然懂了。
学习的最好的办法仍是实践;就譬如我这样动起手来,画图和敲代码等等,比只看而不去动手,要了解得更加透彻!
你的赞是对我最大的支持,也是我最大的动力!post