javascript - 使用 Function.apply() 构造具有原型(prototype)的对象

标签 javascript inheritance constructor prototype instance

我在理解 JS 的原型(prototype)继承时遇到了一些困境。我想做的是:

  1. 定义一个名为mod的对象

    var mod = function() {
        function sayGoodbye() {
            alert("Goodbye!");
        }
    
        function saySomethingElse(message) {
            alert(message);
        }
    
        return {
            sayGoodbye: sayGoodbye,
            saySomethingElse: saySomethingElse
        };
    };
    
  2. 定义一个名为 proto 的原型(prototype)对象

    var proto = {
        sayHello: function() {
            alert("Hello!");
        }
    };
    
  3. mod的原型(prototype)设置为proto

    mod.prototype = proto;
    
  4. 调用一个函数,该函数使用 proto 原型(prototype)构造 mod 的新实例

    function construct(constructor, args) {
    
        function constructorWrapper() {
            return constructor.apply(this, args)
        }
    
        constructorWrapper.prototype = constructor.prototype;
    
        return new constructorWrapper();
    }
    
    var foo = construct(mod, ["Other Message 1"]);
    var bar = construct(mod, ["Other Message 2"]);
    
    console.dir(foo);
    console.dir(bar);
    

construct函数使用apply函数正确创建mod的新实例,但它的原型(prototype)不是proto>。我错过了什么阻止 modproto 作为原型(prototype)构建?

这是一个fiddle与上面的代码。

谢谢!!

最佳答案

.prototype 赋值对您不起作用的原因是,只有当您在构造函数上使用 new 运算符时,这样设置原型(prototype)链才有效。

您创建了一个返回新创建对象的工厂函数。摆脱 mod 中的 return 并使用 this 附加您的方法,并在创建实例时使用 new 运算符mod 将使 .prototype 分配起作用。

这可能会令人困惑,所以我更新了你的 fiddle : https://jsfiddle.net/6fdo649y/1/

有多种方法可以实现您想要做的事情,但这个示例解释了为什么您看不到 .prototype 工作。

//Constructor function using this
function Mod(arg1) {
    this.sayGoodbye = function sayGoodbye() {
        alert("Goodbye!");
    }

    this.saySomethingElse = function saySomethingElse(message) {
        alert(message);
    }

    this.arg1 = arg1;
};

var proto = {
    sayHello: function() {
        alert("Hello!");
    }
};

Mod.prototype = proto;

function construct(constructor, args) {

    function constructorWrapper() {
        constructor.apply(this, args)
    }

    constructorWrapper.prototype = constructor.prototype;

    return new constructorWrapper();
}

var foo = construct(Mod, ["Other Message 1"]);
var bar = construct(Mod, ["Other Message 2"]);

console.dir(foo === bar);
console.dir(foo);
console.dir(bar);

已编辑:添加了通过 apply 传递参数。

关于javascript - 使用 Function.apply() 构造具有原型(prototype)的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35618637/

相关文章:

c++ - 当成员变量的大小只为派生类所知时,如何在基类函数中使用成员变量

c++ - 通过零参数构造函数生成的 glm::mat4 应该包含哪些值?

javascript - this 在 underscore.js 的函数 "_"中

javascript - 复活节彩蛋 - 字母间距

javascript - JS 正则表达式 : how to match "for (...)" but not "for...of" or "for...in"

c++ - 派生类的复制构造函数

Python 在没有 __init__ 的情况下触发 __new__?

javascript - 从 AngularJS 中的 JSON 数组获取值

javascript - 仅 HTML/JS 和谷歌地图上的实时 GPS 跟踪器可以在手机上运行?可能吗?

python - 如何使用 Django 和 South 创建父类(super class)(针对现有模型)