1、原型链继续
中心: 将父类的实例作为子类的原型
瑕玷: 父类新增原型要领/原型属性,子类都能访问到,父类一变别的的都变了
function Person (name) {
this.name = name;
};
Person.prototype.getName = function () { //对原型举行扩大
return this.name;
};
function Parent (age) {
this.age = age;
};
Parent.prototype = new Person('老明'); //这一句是症结 //经由过程组织器函数建立出一个新对象,把老对象的东西都拿过来。
Parent.prototype.getAge = function () {
return this.age;
};
// Parent.prototype.getName = function () { //能够重写从父类继续来的要领,会优先挪用本身的。
// console.log(222);
// };
var result = new Parent(22);
console.log(result.getName()); //老明 //挪用了从Person原型中继续来的要领(继续到了当前对象的原型中)
console.log(result.getAge()); //22 //挪用了从Parent原型中扩大来的要领
2、组织继续
基本思想
借用组织函数的基本思想就是应用call
或许apply
把父类中经由过程this
指定的属性和要领复制(借用)到子类建立的实例中。
由于this
对象是在运行时基于函数的实行环境绑定的。也就是说,在全局中,this
即是window
,而当函数被作为某个对象的要领挪用时,this
即是谁人对象。call
、apply
要领可将一个函数的对象上下文从初始的上下文转变为由 thisObj 指定的新对象。
所以,这个借用组织函数就是,new
对象的时刻(new建立的时刻,this
指向建立的这个实例),建立了一个新的实例对象,
而且实行Parent
内里的代码,而Parent
内里用call
挪用了Person
,也就是说把this
指向改成了指向新的实例,
所以就会把Person
内里的this
相干属性和要领赋值到新的实例上,而不是赋值到Person
上面,
所以一切实例中就具有了父类定义的这些this
的属性和要领。
由于属性是绑定到this
上面的,所以挪用的时刻才赋到响应的实例中,各个实例的值就不会相互影响了。
中心:运用父类的组织函数来加强子类实例,即是是复制父类的实例属性给子类(没用到原型)
瑕玷: 要领都在组织函数中定义, 只能继续父类的实例属性和要领,不能继续原型属性/要领,没法完成函数复用,每一个子类都有父类实例函数的副本,影响机能
function Person (name) {
this.name = name;
this.friends = ['小李','小红'];
this.getName = function () {
return this.name;
}
};
// Person.prototype.geSex = function () { //对原型举行扩大的要领就没法复用了
// console.log("男");
// };
function Parent = (age) {
Person.call(this,'老明'); //这一句是中心症结
//如许就会在新parent对象上实行Person组织函数中定义的一切对象初始化代码,
// 效果parent的每一个实例都邑具有本身的friends属性的副本
this.age = age;
};
var result = new Parent(23);
console.log(result.name); //老明
console.log(result.friends); //["小李", "小红"]
console.log(result.getName()); //老明
console.log(result.age); //23
console.log(result.getSex()); //这个会报错,挪用不到父原型上面扩大的要领
3、组合继续
组合继续(一切的实例都能具有本身的属性,而且能够运用雷同的要领,组合继续防止了原型链和借用组织函数的缺点,连系了两个的长处,是最经常使用的继续体式格局)
中心:经由过程挪用父类组织,继续父类的属性并保留传参的长处,然后再经由过程将父类实例作为子类原型,完成函数复用
瑕玷:挪用了两次父类组织函数,生成了两份实例(子类实例将子类原型上的那份屏障了)
function Person (name) {
this.name = name;
this.friends = ['小李','小红'];
};
Person.prototype.getName = function () {
return this.name;
};
function Parent (age) {
Person.call(this,'老明'); //这一步很症结
this.age = age;
};
Parent.prototype = new Person('老明'); //这一步也很症结
var result = new Parent(24);
console.log(result.name); //老明
result.friends.push("小智"); //
console.log(result.friends); //['小李','小红','小智']
console.log(result.getName()); //老明
console.log(result.age); //24
var result1 = new Parent(25); //经由过程借用组织函数都有本身的属性,经由过程原型享用大众的要领
console.log(result1.name); //老明
console.log(result1.friends); //['小李','小红']
4、寄生组合继续
中心:经由过程寄生体式格局,砍掉父类的实例属性,如许,在挪用两次父类的组织的时刻,就不会初始化两次实例要领/属性,防止的组合继续的瑕玷
瑕玷:可谓圆满,但完成较为庞杂
function Person(name) {
this.name = name;
this.friends = ['小李','小红'];
}
Person.prototype.getName = function () {
return this.name;
};
function Parent(age) {
Person.call(this,"老明");
this.age = age;
}
(function () {
var Super = function () {}; // 建立一个没有实例要领的类
Super.prototype = Person.prototype;
Parent.prototype = new Super(); //将实例作为子类的原型
})();
var result = new Parent(23);
console.log(result.name);
console.log(result.friends);
console.log(result.getName());
console.log(result.age);