【问题标题】:Employing inheritance with JavaScript Function objects使用 JavaScript 函数对象继承
【发布时间】:2023-04-11 10:22:01
【问题描述】:

是否可以创建两个或多个继承公共对象属性的 JavaScript 函数对象?

var obj common = {
    a: 'first',
    b: 'second',
    z: 'last'
};

var foo = function() {};
var bar = function() {};

// Some magic occurs here

foo.a; // 'first'
bar.z; // 'last'

实现这一点的一种方法是使用 mixin,我们在其中迭代 common 并将属性复制到 foo 和 bar。但是,如果我们有一个庞大的属性列表,这可能会变得低效。

有没有更多的 JavaScript 方式来做到这一点?我很想在这里使用原型链,但我不知道是否可能。

【问题讨论】:

    标签: javascript inheritance prototype prototypal-inheritance


    【解决方案1】:

    不可能以以下方式创建函数:

    • function foo (){ }(函数声明)
    • Function 构造函数
    • var foo = function(){ }(函数表达式)
    • () => {}(ES6 箭头)。

    在所有这些中,您不能为函数本身指定基类。但是,正如您所指出的,类似 mixin 的技巧在这里可以正常工作。

    请注意,事先可能有人认为以下方法可能有效:

    function f(){
       return Function.apply(this, arguments);
    }
    f.prototype = Object.create(Function.prototype);
    f.x = 15;
    

    但事实并非如此,它也不符合规范(即,因为作为函数调用的函数构造函数行为相同 - 即它忽略传入的 this)。

    【讨论】:

      【解决方案2】:

      这正是你想要的,但我不认为你想要你想要的。如果你明白我的意思吗?!

      这需要现代 Chrome 或 FF:

      var common = {
          __proto__: Function.prototype,
          a: 'first',
          b: 'second',
          z: 'last'
      };
      
      var foo = function() {};
      var bar = function() {};
      
      Object.setPrototypeOf(foo, common);
      Object.setPrototypeOf(bar, common);
      
      console.log(foo.a); // 'first'
      console.log(bar.z); // 'last'
      

      我想你想要的是这样的:

      var common = {      
        a: 'first',
        b: 'second',
        z: 'last'
      };
      
      var Foo = function() {};
      var Bar = function() {};
      
      Foo.prototype = Bar.prototype = common;
      
      var foo = new Foo();
      var bar=  new Bar();
      
      console.log(foo.a); // 'first'
      console.log(bar.z); // 'last'
      

      【讨论】:

      • 不,我特别想创建从公共父原型继承的对象,但也可以将其作为函数应用于参数。谢谢!
      • 如果我没记错的话,直接设置proto一般不是个好主意。这可以通过额外调用 Object.setPrototypeOf(common, Function.prototype) 来完成吗?
      • 另外,Safari 似乎不支持 setPrototypeOf。
      • 我的回答中的前一种方法违背了语言的本质,因此它使用了广泛支持的结构/方法。后一种方法更传统,利用原型链。
      • 确实如此;但他们实现不同的目标。您的第二种方法为函数对象的实例设置原型链,而我想设置函数对象本身的原型链。似乎 Javascript 编写者并不打算让程序员这样做。
      猜你喜欢
      • 1970-01-01
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多