当前位置: 代码迷 >> 综合 >> JavaScript中常用的继承
  详细解决方案

JavaScript中常用的继承

热度:88   发布时间:2024-01-29 07:59:01.0

// 1. 原型链继承:子类构造函数的原型对象指向父类构造函数的实例

/*

缺点: 1.子类的实例会共享父类的引用类型的属性

2. 调用父类方法的时候无法向父类传递参数

**/

// 父类

function SuperClass() {

// 引用属性

this.books = ['javaScript', 'css世界', 'html'];

// 普通属性

this.superValue = true;

}

SuperClass.prototype.getBooks = function() {

return this.books;

}

// 子类

SuperClass.prototype.superName = 'super';

function SubClass(name) {

this.name = name

this.subValue = false;

}

SubClass.prototype = new SuperClass();

// 子类自己的方法

SubClass.prototype.getSubValue = function() {

return this.subValue;

}

// 测试例子

var instance1 = new SubClass('instance1');

var instance2 = new SubClass('instance2');

console.log(instance1.books); //["javaScript", "css世界", "html"]

console.log(instance2.books); //["javaScript", "css世界", "html"]

instance1.books.push('数据结构');

console.log(instance1.books); //["javaScript", "css世界", "html", "数据结构"]

console.log(instance2.books); //["javaScript", "css世界", "html", "数据结构"]

// instanceof 判断一个对象是否是一个类的实例,或一个对象是否继承一个类

console.log(instance1 instanceof SubClass); // true

console.log(instance1 instanceof SuperClass); // true

console.log(SubClass instanceof SuperClass); // false

console.log(SubClass.prototype instanceof SuperClass); // true

console.log(instance1.superName); //super

 

// 2.  构造继承:在子类的构造函数中调用父类函数

/*

缺点: 1. 无法继承父类的原型属性和原型方法

优点: 1. 解决了原型继承中子类实例共享父类引用属性的问题

            2. 调用父类构造函数时无法传递参数的问题

*/

// 父类

function SuperClass(id) {

// 引用属性

this.books = ['javaScript', 'css世界', 'html'];

// 普通属性

this.superValue = true;

this.id = id;

}

SuperClass.prototype.getBooks = function() {

return this.books;

}

SuperClass.prototype.name = 'super'

// 子类

function SubClass(id) {

this.subValue = false;

SuperClass.call(this, id);

}

// 测试例子

var instance1 = new SubClass('instance1')

var instance2 = new SubClass('instance2')

console.log(instance1.books); //["javaScript", "css世界", "html"]

console.log(instance2.books); //["javaScript", "css世界", "html"]

console.log(instance2.getBooks); //undefined

console.log(instance2.superName); //undefined

instance1.books.push('数据结构');

console.log(instance1.books); //["javaScript", "css世界", "html", "数据结构"]

console.log(instance2.books); //["javaScript", "css世界", "html"]

console.log(instance1.id); //instance1

console.log(instance2.id); //instance2

/*

3. 组合继承: 原型继承+构造继承(即在子类的构造函数中执行父类构造函数,将子类的原型对象指向为父类的实例)

优点: 1. 可以向父类构造函数中传递参数

            2. 子类的实例不会共享父类的引用属性

            3. 子类可以继承父类的原型属性和原型方法

缺点:父类构造函数执行了两次

*/

// 父类

function SuperClass(name) {

this.name = name;

this.books = ['javaScript', 'CSS世界', 'html布局大全'];

}

// 父类原型方法

SuperClass.prototype.getName = function() {

return this.name;

}

SuperClass.prototype.superValue = true;

// 子类

function SubClass(name, price) {

SuperClass.call(this, name); //第二次调用父类构造函数(在新对象上创建了实例属性,会屏蔽掉原型上同名的属性)

this.price = price;

}

SubClass.prototype = new SuperClass(); //第一次调用父类构造函数(此时父类的实例属性和原型属性均会在子类的原型上)

// 修改子类的原型对象破坏了constructor属性,所以对constructor重新赋值

SubClass.prototype.constructor = SubClass;

// 测试例子

var instance1 = new SubClass('instance1', 65.6);

console.log(instance1.getName()); //instance1

console.log(instance1.books); //["javaScript", "CSS世界", "html布局大全"]

instance1.books.push('数据结构');

console.log(instance1.books); //["javaScript", "CSS世界", "html布局大全", "数据结构"]

console.log(instance1.superValue); //true

var instance2 = new SubClass('instance2', 86.8);

console.log(instance2.getName()); //instance2

console.log(instance2.books); //["javaScript", "CSS世界", "html布局大全"]

console.log(instance2.superValue); //true

/*

4.  寄生组合式继承:寄生式继承 + 构造继承

优点: 1. 父类构造函数只需要执行一次;

             2. 解决父类实例属性即在子类的原型上存在,又在子类的实例属性上存在

**/

// 创建一个空的过渡函数,让其继承父类构造函数,并返回过渡函数的一个实例

// 目的: 用于继承父类原型属性和原型方法

function inheriteObject(obj) {

function F() {}

F.prototype = obj;

return new F();

}

/*

寄生式继承,继承原型

**/

function inheritPrototype(subClass, superClass) {

var p = inheriteObject(superClass.prototype);

// 原本的 p.constructor === SuperClass

p.constructor = subClass;

subClass.prototype = p;

}

// 父类

function SuperClass(name) {

this.name = name;

this.books = ['javaScript','css世界','html布局大全'];

}

SuperClass.prototype.getName = function() {

return this.name;

}

// 子类

function SubClass(name, price) {

// 构造函数式继承,(继承父类的实例属性和实例方法)

SuperClass.call(this, name);

this.price = price;

}

inheritPrototype(SubClass, SuperClass);

// 测试例子

var instance1 = new SubClass('css世界', 45)

console.log(instance1.books); //["javaScript", "css世界", "html布局大全"]

instance1.books.push('数据结构与算法')

console.log(instance1.books); // ["javaScript", "css世界", "html布局大全", "数据结构与算法"]

var instance2 = new SubClass('javaScript设计模式', 55)

console.log(instance2.books); //["javaScript", "css世界", "html布局大全"]

 

  相关解决方案