使用 Function.apply() 构造一个带有原型的对象

Construct an object with a prototype using Function.apply()

本文关键字:原型 对象 一个 apply Function 使用      更新时间:2023-09-26

我对JS的原型继承有点进退两难。我想做的是:

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

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

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

    mod.prototype = proto;
    
  4. 调用一个函数,该函数使用原型原型构造新的 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);
    

构造函数使用 apply 函数正确创建 mod 的新实例,但它的原型不是原型。我缺少什么来阻止模以原型作为原型构建?

这是对上述代码的小提琴。

谢谢堆!!

.prototype赋值不适合您的原因是,仅当您在构造函数上使用 new 运算符时,才能像这样设置原型链。

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

这可能会令人困惑,所以我更新了你的小提琴: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);

已编辑:在传递参数时添加了应用。