js继承方式

继承方式

原型链继承

优点:函数方法可重用

缺点:

  1. 引用值属性被共享
  2. 子类实例化时,不能向父类传递参数

  function Person(name,age){
      this.name = name;	
      this.age = age;
      this.say = "说话";
      this.colors = ["red","green"];
  }
  Person.prototype.sayName = function (){
    console.log(this.say);
  }
  function Man (){ }
  Man.prototype = new Person();
  var zhangsan = new Man('zhangsan', 18);
  console.log(zhangsan.name, zhangsan.age);  // 无法通过子类向父类传递参数 undefined, undefined
  zhangsan.sayName(); // "说话"
  console.log(zhansan.color); 
  • 原型中包含的引用值会被所有实例间共享问题
	function Person() {
   		this.say = "说话";
   		this.colors = ["red", "green"];
	}
	function Man() {}
	Man.prototype = new Person();

	let man1 = new Man();
	man1.colors.push("yellow");
	console.log(man1.colors);  // ["red", "green", "yellow"]

	let man2 = new Man();
	console.log(man2.colors);  // ["red", "green", "yellow"]

盗用构造继承

优点:可以传递参数
缺点:函数无法重用,所有方法都在构造函数内,每次创建对象都会创建对应的方法,大大浪费内存


function Person(name,age,sex){
    this.name = name
    this.age = age
    this.sex = sex
    this.sayName = function(){
        console.log(this.name)
    }
}

function Child(name,age,sex){
    Person.call(this,name,age,sex)
}
let child = new Child('lisi' , 18, '男')
console.log(child)   //Child { name: 'lisi', age: 18, sex: '男', sayName: [Function] }

组合继承

构造函数继承实例属性,原型链继承原型链上的属性和方法

这种方式充分利用了原型链与构造函数各自的优点,是JS中最常用的继承方法

组合模式(构造函数继承 + 原型链继承)


function Animal(name,age){
    this.name = name
    this.age = age
}
Animal.prototype.sayName = function () {
    console.log(this.name)
}
function Cat(name,age,color){
    Animal.call(this,name,age)
    this.color = color;
}
Cat.prototype = new Animal();  //将Cat的原型指向Animal的原型
let cat = new Cat('xiaobai',3,'white');
console.log(cat) //Cat { name: 'xiaobai', age: 3, color: 'white' }
cat.sayName();   //xiaobai

原型式继承

本质就临时创建一个构造函数,将传入的对象赋值给这个构造函数的原型(浅克隆)

适用:不需要单独创建构造函数,但是仍然需要在对象间共享信息的场合。

缺点:引用值还是会被共享。

const person = {
  name : "Nicholas",
  friends: ["Shelby", "Court"]
}
const person1 = object(person);

// 方式1;
        function object (o){
            function F(){};
            F.prototype = o;
            return new F(); 
        }

// 方式2;大写的Object
        Object.create(o); 
// 一样的效果

寄生式继承

和原型式继承接近,创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象。

缺点:函数无法重用

function object (o){
    function F(){};
    F.prototype = o;
    return new F(); 
}
function createAnother(original){
  let clone = object(original);   // 任何返回新对象的函数都可以。不一定要用object
  clone.sayHi = function (){ };
  return clone;
}

寄生组合继承

避免了组合继承的缺点,父类构造函数不会被调用两次。

父类构造器可能有很多方法和属性,创建临时的空实例代替父类传递原型,可以提高效率。

function Animal(){ }
Animal.prototype.eat = function (){ console.log("吃") }

function Cat(name) {
	Animal.call(this);
	this.name = name || 'Tom';
}
function object (o){
    function F(){};
    F.prototype = o;
    return new F(); 
}
function inheritPrototype(SubType, SuperType){
  let prototype = object(SuperType.prototype);
  prototype.constructor = SubType;   // 增强对象
  subType.prototype = prototype;  // 赋值对象
}

inheritPrototype(Cat, Animal);

let cat = new Cat();
console.log(cat.name);		//Toms
cat.eat();  // "吃"
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

ES6继承

原型链继承的语法糖

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值