首页 > 请教一下,JavaScript中继承应该怎么实现

请教一下,JavaScript中继承应该怎么实现

我不知道JavaScript中有没有继承这个概念。
在Java中继承是指类之间的继承,它的意义在于代码复用和多态,父类A,对应实例对象a,子类B,对应实例对象b,继承指的是类B继承了类A的属性和方法,至于a和b没什么直接关系。
而在JavaScript中好像没有明确的类的概念,它是基于对象的,而这个对象又和Java中的不同,Java中的对象一经实例之后是不能增删属性或方法的,而JavaScript则可以对对象任意修改。Jav中对象是由类实例化得来的,JavaScript中是由函数实例化来的:
var str = new String("实例初始化String");
var obj1 = new Object();
var obj2 = new 自定义函数();
那么我们讨论JavaScript中的继承,是不是就指的是这些函数间的继承呢?
JavaScript中对象的__proto__和继承是不是没有关系呢?
求指点,谢谢每位回复的人!


两种方式:
使用call 改变this
使用 prototype 原型链


es6有标准的class和extend关键字实现继承,其它情况建议使用兼容node的inherits写法。
https://github.com/component/inherits/blob/master/inherits_browser.js

if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    ctor.prototype = Object.create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  };
} else {
  // old school shim for old browsers
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    var TempCtor = function () {}
    TempCtor.prototype = superCtor.prototype
    ctor.prototype = new TempCtor()
    ctor.prototype.constructor = ctor
  }
}

这是兼容旧浏览器的一种方式,其实主要是prototype继承以及构造函数重写罢了


可以看一下这篇文章
js继承


function Pet() {
    this.type = 'pet';
}

Pet.prototype.getType = function() {
    return this.type;
};

function Cat() {
    Pet.apply(this, arguments);   // apply super constructor

    this.type = 'cat';
}

Cat.prototype = Object.create(Pet.prototype);
Cat.prototype.constructor = Cat;

var cat = new Cat;
console.log(cat.getType());         // 'cat'
console.log(cat instanceof Pet);    // true

JavaScript 的类和继承

JavaScript 中没有类和继承,只有原型和对象。类是用 function 模拟的(以 function 作为构建函数),继承其实就是原型链。

ES2015 中出现了 classextends,以更简捷的语法描述了类和继承,然而实质也是通过 function 和原型链来实现的(据说是,我没验证过)

JavaScript 是一种脚本,动态语言,而 Java 是一种静态语言,所以 JavaScript 在写法上比 Java 灵活很多,不能完全的拿 Java 的思想去套 JavaScript。关于 JavaScript 对象可以任意添加属性这个问题,你可以把它想像成是一个 java.util.HashMap 对象。

这涉及到很多 JavaScript 核心的东西,需要慢慢领会。你可以在网上搜搜这方面的文章来看,比如搜 JavaScript 继承的实现,就能搜出 N 种方法来。

关于继承的实现

这个事情,我比较推荐使用 TypeScript 翻译出来的 JS,

// TypeScript

class Pet {
    type;
    constructor(type) {
        this.type = type;
    }
    
    getPetType() {
        return this.type;
    }
}

class Cat extends Pet {
    constructor() {
        super("cat");
    }
}

var cat1 = new Pet("cat");
var cat2 = new Cat();

console.log(cat1.getPetType());
console.log(cat2.getPetType());

翻译出来

// JavaScript

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Pet = (function () {
    function Pet(type) {
        this.type = type;
    }
    Pet.prototype.getPetType = function () {
        return this.type;
    };
    return Pet;
})();
var Cat = (function (_super) {
    __extends(Cat, _super);
    function Cat() {
        _super.call(this, "cat");
    }
    return Cat;
})(Pet);
var cat1 = new Pet("cat");
var cat2 = new Cat();
console.log(cat1.getPetType());
console.log(cat2.getPetType());

// 继承函数
function classExtends(child,parent) {
        var key;
        for( key in parent){
            if(parent.hasOwnProperty(key)){
                child[key] = parent[key];
            }
        }
        function ctor(){this.constructor = child;}
        ctor.prototype = parent.prototype;
        child.prototype = new ctor();
        // Cat.SUPER == Pet.prototype
        child.SUPER = parent.prototype;
}

function Pet(type){ this.type=type; }
// 这一句不要写在函数里面
Pet.prototype.getPetType=function(){ return this.type; }

classExtends(Cat,Pet)
function Cat(type){
    Cat.SUPER.constructor.call(this,"cat");
}

var cat1 = new Cat();
console.log(cat1.getPetType());
var cat2 = new Cat();
console.log(cat2.getPetType());
【热门文章】
【热门文章】