【问题标题】:The equivalent to using __proto__?相当于使用 __proto__?
【发布时间】:2017-02-03 20:44:04
【问题描述】:

我正在尝试将显示模块模式与继承一起使用。我似乎让它工作正常,但它使用“__proto__”,我知道它被认为已弃用。有没有更好的方法是在不使用“__proto__”的情况下创建继承?

var Person = (function() {
    var _name;
    var api = {
        init: init,
        getName: getName
    }
    return api;

    function init(name) {
        _name = name;
    }

    function getName() {
        return _name;
    }
}())

var Teacher = (function() {
    var _subject = "Math";
    var api = {
        getSubject: getSubject,
        say: say
    }
    api.__proto__ = Person;
    return api;

    function getSubject() {
        return _subject;
    }

    function say() {
        console.log("I am " + this.getName() + " and I teach " + _subject)
    }
}());

Teacher.init("Bob");
Teacher.say() //  I am Bob and I teach math

https://plnkr.co/edit/XbGx38oCyvRn79xnn2FR?p=preview

【问题讨论】:

  • Object.create让你在创建时设置它,我不明白为什么你需要在创建对象后设置原型链。

标签: javascript inheritance revealing-module-pattern


【解决方案1】:

直接的等价物——设置原型,仍然是个坏主意——是Object.setPrototypeOf

Object.setPrototypeOf(api, Person);

不过,使用Object.create 基于原型创建对象然后向其添加属性的常规方法在这里可以正常工作:

var api = Object.create(Person);
api.getSubject = getSubject;
api.say = say;

但理想情况下,您应该只使用构造函数:

class Person {
    constructor(name) {
        this._name = name;
    }

    getName() {
        return this._name;
    }
}

class Teacher extends Person {
    constructor(name) {
        super(name);
        this._subject = 'Math';
    }

    getSubject() {
        return this._subject;
    }

    say() {
        console.log(`I am ${this.getName()} and I teach ${this.getSubject()}`);
    }
}

var teacher = new Teacher('Bob');
teacher.say() //  I am Bob and I teach math

没有 ES6:

function Person(name) {
    this._name = name;
}

Person.prototype.getName = function () {
    return this._name;
};

function Teacher(name) {
    Person.call(this, name);
    this._subject = 'Math';
}

Teacher.prototype = Object.create(Person.prototype);

Teacher.prototype.getSubject = function () {
    return this._subject;
};

Teacher.prototype.say = function () {
    console.log('I am ' + this.getName() + ' and I teach ' + this.getSubject());
};

var teacher = new Teacher('Bob');
teacher.say();  // I am Bob and I teach math

【讨论】:

  • 不幸的是,JS6 不是一个选项,但 Object.create() 成功了——在 jquery 的帮助下: $.extend(api, Object.create(Person));
  • @Skyler:你为什么需要$.extend?无论如何,你不必使用 ES6 类来使用构造函数;见编辑。
  • 我喜欢在代码块顶部的 api 对象中定义我的公共方法。所以我然后使用 $.extend 将它与基础对象结合起来。
猜你喜欢
  • 2015-02-08
  • 2012-01-14
  • 2017-02-01
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 2012-09-17
  • 2011-07-20
相关资源
最近更新 更多