美文网首页
基于javascript的对象继承

基于javascript的对象继承

作者: 陆霁 | 来源:发表于2018-01-23 17:29 被阅读6次

谈到继承,javascript在ES6出现之前,是不提供原生的继承机制的,这里我们将通过几种方法,来实现功能上的继承。

1.基于原型链的继承

function SuperType(){
    this.colors=["red", "blue", "green"]
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
}
function SubType(){
}
SubType.prototype = new SuperType();
SubType.prototype.getSuperValue = function(){
    return this.subproperty;
}
SubType.prototype.getSuperValue = function(){
    return false;
}
var instance1 = new SubType();
instance1.colors.push("black");
var instance2 = new SubType();
console.info(instance2.colors)

result:  [ 'red', 'blue', 'green', 'black' ]
console.info(instance1.hasOwnProperty("colors"), "colors" in instance1)
result: false true           //说明colors这个属性不是子类的实例属性,而是原型属性

着重看第9行,子类的原型指向父类的实例,同样也就继承了父类实例后的所有属性,追着父类实例的原型链走,同样也继承到了父类的方法。

缺点:虽然得到了父类的属性和方法,但是都是在原型上的,当某一个实例对其属性进行更改时,会直接反应到原型上,如果这时实例化另外一个实例的话,就将接受这种更改,这往往是不能接受的,这在倒数。


2.借用构造函数来实现继承

function SuperType(){
    this.colors=["red", "blue", "green"]
}
function SubType(){
   SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("black");
console.info(instance1.colors)  //red, blue, green, black

var instance2 = new SubType();
console.info(instance2.colors)  //red, blue, green

console.info(instance1.hasOwnProperty("colors"), "colors" in instance1)
result: true true

着重看第五行,用了构造函数的call方法, call方法作用在与改变函数执行的作用域,第五行传入的this.也就是子类运行时的作用域,我们把子类作用域传入父类作用域,导致父类定义的那些属性会直接挂载到子类的作用域里,这个时候我们对子类进行实例化后得到的属性为实例属性。这个时候对各种对属性进行操作就不会影响到其他实例了。

缺点:如果方法也按照借用构造函数进行继承的话,那么方法他在每一个实例都会有一个拷贝,显然如果每个实例方法都是一样的话,会造成大量资源的浪费。


3.组合继承

组合继承: 我们把想要继承的属性通过借用构造函数的方法,把方法通过原型链进行继承。

function SuperType(name){
    this.name = name;
    this.colors=["red", "blue", "green"]
}
SuperType.prototype.sayName = function(){
    console.info(this.name);
}
//借用构造函数完成属性的继承
function SubType(name, age){
    SuperType.call(this, name); //添加公共属性
    this.age = age;  //添加自有属性
}
//借用原型链实现方法的继承
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    console.info(this.age);
}

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
console.info(instance1.colors)  //red, blue, green, black
instance1.sayName();  //"Nicholas"
instance1.sayAge()    //29
var instance2 = new SubType("Greg", 27);
console.info(instance2.colors) //red, blue, green
instance2.sayName()  //"Greg"
instance2.sayAge()   //27

但是细心的你会发现我们在借用原型链实现方法的继承时,不仅把父类的方法挂载到原型上,父类的属性也挂载到了原型上,但是我们也借用构造函数实现实例属性的继承,而原则上是不需要挂载属性的,这就造成了原型上属性的冗余。

那么如何规避这种冗余呢?

function SuperType(name){
    this.name = name;
    this.colors=["red", "blue", "green"]
}
SuperType.prototype.sayName = function(){
    console.info(this.name);
}
//借用构造函数完成属性的继承
function SubType(name, age){
    SuperType.call(this, name); //添加公共属性
    this.age = age;  //添加自有属性
}
//借用原型链实现方法的继承
function F(){}
//这样就只继承到了父类原型上的方法。
F.prototype = SuperType.prototype;
SubType.prototype = new F();

// SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    console.info(this.age);
}

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
console.info(instance1.colors)  //red, blue, green, black
instance1.sayName();  //"Nicholas"
instance1.sayAge()    //29
var instance2 = new SubType("Greg", 27);
console.info(instance2.colors) //red, blue, green
instance2.sayName()  //"Greg"
instance2.sayAge()   //27

这是javascript实现继承的终极方法,很多流行的前端框架内部继承的实现也是基于这一方法的。

相关文章

  • 基于javascript的对象继承

    谈到继承,javascript在ES6出现之前,是不提供原生的继承机制的,这里我们将通过几种方法,来实现功能上的继...

  • JS 中的一些概念问题

    Q:描述 JavaScript 中的继承和原型链,并举例子。 JavaScript 是基于原型的面向对象语言,并无...

  • javascript面向对象的不同之处

    MDN参考文档 ---mdn 上的文档质量高! javascript的面向对象继承概念是指基于原型的继承,java...

  • JavaScript基础⑤ES6中的面向对象

    接续上篇JavaScript基础④基于原型的面向对象编程 前言 面向对象语言的基本特征:封装,继承,多态 。 这是...

  • javascript代码积累

    一、javascript实现继承 1.基于原型链实现继承 2.基于属性和方法复制实现继承 二、javascript...

  • Web前端经典面试试题及答案2

    javascript面向对象中继承实现? 面向对象的基本特征有:封闭、继承、多态。在JavaScript中实现继承...

  • 菜鸟学习javascript10

    12javascript对象 1.基于对象的操作方式(面向对象封装、继承、多态) 2.将相关的操作使用一个对象完成...

  • 函数的原型对象

    什么是原型? 原型是Javascript中的继承的继承,JavaScript的继承就是基于原型的继承。 函数的原型...

  • JavaScript基础系列之——继承

    一、基本概念: JavaScript基于原型实现面向对象特性,在JS编程中,面向对象的继承是重点,本文将从简单...

  • javascript对象继承顺序、分类和内置Math对象

    javascript对象继承顺序、分类和内置Math对象 一、对象的继承顺序 所有对象都是从Object对象继承过...

网友评论

      本文标题:基于javascript的对象继承

      本文链接:https://www.haomeiwen.com/subject/rugsaxtx.html