javascript - 高级 Javascript : Detecting whether current function is being called by a constructor

标签 javascript oop prototype

在 Javascript 函数中,检测函数是简单执行还是作为对象实例构造函数执行(使用 new 关键字)是一种相当简单的检测。

// constructor
function SomeType() {
    if (this instanceof SomeType)
        // called as an object instance constructor
    else
        // the usual function call
}

没关系,这已经在 SO 上至少回答过几次了。

现在让我们假设我们的构造函数调用我直接在 Function 原型(prototype)上定义的另一个函数,因此所有函数都可以访问 - 这就是我这样做的主要目的。

Function.prototype.doSomething = function doSomething() {
    // what code here?
};

// constructor
function SomeType() {
    SomeType.doSomething();
}

主要问题

我们现在如何在 doSomething 中检测 SomeType 函数?

我想要检测它的原因是我正在编写一个函数,该函数采用/注入(inject)构造函数参数作为具有相同名称的构造对象实例成员。当然,这个函数应该只在被构造函数调用时执行,而不是被定期调用的函数调用。

This is my answer另一个问题,您可以在其中看到我的 adoptArguments 函数,该函数将对象构造函数参数作为成员放入构造的对象实例中。

强制执行特定用法的解决方法 = 错误

我有一个我不想使用的可能的解决方法,因为它强制执行正确的用法 - 执行上下文注入(inject)。这是可以检测对象实例构造函数执行的代码:

Function.prototype.doSomething = function doSomething() {
    if (this instanceof doSomething.caller)
    {
        // object instance construction
    }
    else return; // nope, just normal function call
};

// constructor
function SomeType() {
    // required use of ".call" or ".apply"
    SomeType.doSomething.call(this);
}

这个想法可能会激发你自己的一些想法来解决原来的问题

最佳答案

Within a Javascript function it is a rather simple detection whether the function has been simply executed or being executed as an object instance constructor (using new keyword).

其实那是不可能的,一个cannot know在 JS 中,用户函数是否作为构造函数被调用。 this instanceof 测试对于通常情况来说已经足够了,但它只检查上下文是否确实继承自类的原型(prototype)。

How can we now detect within doSomething the same for SomeType function?

出于同样的原因,您不能执行 instanceof 测试而不将 this 作为参数传递给您的 doSomething

Main problem: I'm writing a function that adopts/injects constructor parameters as constructed object instance members with the same name.

我建议不要通过构造函数内部的函数调用来这样做。相反,尝试修饰构造函数,以便您可以立即访问所需的所有值:

Function.prototype.adoptArguments = function() {
    var init = this;
    var args = arguments.length ? arguments : init.toString().replace(comments, "").match(argumentsparser);

    if (!args || !args.length) return init;

    var constructor = function() {
        if (this instanceof constructor) {
            for (var i=0; i<args.length; i++)
                this[args[i]] = arguments[i];
            init.apply(this, arguments);
        } else {
            // throw new Error("must be invoked with new");
        }
    };
    return constructor;
};

然后代替

function SomeType() {
    SomeType.adoptArguments();
}

var SomeType = function() {

}.adoptArguments();

关于javascript - 高级 Javascript : Detecting whether current function is being called by a constructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27838477/

相关文章:

python - Python 3 类中的复数除法

javascript - 什么取代了 JavaScript 中已弃用的 __proto__

javascript - 如何将一系列 javascript (jQuery) 按钮 "on clicks"转换为循环?

c# - 在高负载系统 C# 中映射 POCO 的成本

javascript - 如何使 Vue 组件与 v-model 保留值类型一起工作?

java - 创建一个单独的对象并从 Java 中的对象引用编辑它

javascript - JS继承的诡异时刻

javascript - 如何在 javascript 中修复此类定义以支持 instanceof 运算符

javascript - 使用 JavaScript 更改 HTML 表单输入

javascript - javascript中的上限十进制格式