小言_互联网的博客

JavaScript继承方式

300人阅读  评论(0)

原型链继承

利用prototype将子构造函数的prototype指向Person达到继承的目的

function Person(name){
    this.name = name;
    this.country='china';
}
Person.prototype.play = function(){
    
}

function Child(age){
    this.age = age;
}

Child.prototype = new Person();

缺点:

  • 创建子类实例时,但是无法给父构造函数传参
  • 来自原型对象的引用属性是所有实例共享的

构造函数继承

在子类构造函数中借用call调用父类构造函数

function Person(name){
    this.name = name;
    this.country='china';
}
Person.prototype.play = function(){
    
}

function Child(name,age){
    this.age = age;
    Person.call(this,name)
}
var obj = new Child('小明',16);

优点:

  • 解决了子类构造函数向父类构造函数传参数和实例共享原型属性的问题

缺点:

  • 相当于每个实例都拷贝了一份父类的方法,占用内存大
  • 不能继承原型属性/方法,只能继承父类的实例属性和方法

组合继承

使用原型链实现对原型属性和方法的继承,通过借用构造函数实现对实例属性的继承

function Person(name){
    this.name = name;
    this.country='china';
}
Person.prototype.play = function(){
    
}
function Child(name,age){
    Person.call(this,name);
    this.age = age;
}
Child.prototype = new Person();

缺点:

  • 会调用两次父类构造函数

原型式继承

基于已有对象,创建新对象

// 在object函数内部,先创建了一个临时的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。
// 从本质上讲,object()对传入其中的对象执行了一次浅复制。

function object (o) {
  function F() {}
  F.prototype = o;
  return new F();
}
缺点:
-  和原型链继承一样,所有子类实例共享父类的引用类型

寄生式继承

寄生式继承是与原型式继承紧密相关的一种思路,创建一个仅用于封装继承过程的函数,该函数内部以某种形式来做增强对象,最后返回对象

function object (o) {
  function F() {}
  F.prototype = o;
  return new F();
}

function createAnother (o) {
  var clone = object(o);
  clone.sayHi = function () {
    console.log('Hi');
  }
  return clone;
}
缺点:
1,和原型链式继承一样,所有子类实例共享父类引用类型。
2,和借用构造函数继承一样,每次创建对象都会创建一次方法

寄生组合式继承

结合组合式继承和寄生式继承,解决组合式继承调用两次父类构造函数的问题

function object(o) {
  function F() { }
  F.prototype = o;
  return new F();
}

function inheritPrototype(SubType, SuperType) {
  var prototype = object(SuperType.prototype);        // 创建对象
  prototype.constructor = SubType;    // 增强对象
  SubType.prototype = prototype;      // 指定对象 
}

// 父类
function SuperType(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function () {
  console.log(this.name);
};

// 子类
function SubType(name, age) {
  // 继承父类实例属性
  SuperType.call(this, name);

  // 子类实例属性
  this.age = age;
}

// 继承父类方法
inheritPrototype(SubType, SuperType);

Es6继承

function object(o) {
  function F() { }
  F.prototype = o;
  return new F();
}

function inheritPrototype(SubType, SuperType) {
  var prototype = object(SuperType.prototype);        // 创建对象
  prototype.constructor = SubType;    // 增强对象
  SubType.prototype = prototype;      // 指定对象 
}

// 父类
function SuperType(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function () {
  console.log(this.name);
};

// 子类
function SubType(name, age) {
  // 继承父类实例属性
  SuperType.call(this, name);

  // 子类实例属性
  this.age = age;
}

// 继承父类方法
inheritPrototype(SubType, SuperType);

`底层也是用寄生组合式继承实现的`

拷贝继承
把一个对象中的属性和方法复制到另一个

浅拷贝
 function shallowCopy(source, target = {}) {
        var key;
        for (key in source) {
            if (source.hasOwnProperty(key)) {        // 意思就是__proto__上面的属性,我不拷贝
                target[key] = source[key];
            }
        }
        return target;
    }

深拷贝 
(对象里面嵌套对象才涉及深拷贝)
function deepCopy(source, target = {}) {
        var key;
        for (key in source) {
            if (source.hasOwnProperty(key)) {                         // 意思就是__proto__上面的属性,我不拷贝
                if (typeof(source[key]) === "object") {               // 如果这一项是object类型,就递归调用deepCopy
                    target[key] = Array.isArray(source[key]) ? [] : {};
                    deepCopy(source[key], target[key]);
                } else {                                            // 如果不是object类型,就直接赋值拷贝
                    target[key] = source[key];
                }
            }

深拷贝黑科技

var targetObj = JSON.parse(JSON.stringify(copyObj))

缺点:
1、如果你的对象里有函数,函数无法被拷贝下来
2、无法拷贝copyObj对象原型链上的属性和方法

转载:https://blog.csdn.net/liu_xiaoru/article/details/102488319
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场