javascript - 删除对 "new"的需要

标签 javascript constructor new-operator factory

javascript 中的一个令人讨厌的问题是忘记在要实例化的函数上调用 new,导致 this 被绑定(bind)到不同的对象(通常是全局对象)一个新鲜的。我读到的一种解决方法是使用以下惯用语在函数构造函数中明确检查它:

function SomeConstructor(x, y, ...) {
    // check if `this` is created with new
    if ( !(this instanceof arguments.callee) )
        return new SomeConstructor(x, y, ...);
    // normal initialization code follows

现在 new SomeConstructor(...)SomeConstructor(...) 是等价的。

我想通过创建一个包装函数 factory(fn) 来简化它,它执行前两行,然后委托(delegate)给包装函数 fn。这将像这样使用:

SomeConstructor = factory(function (x, y, ...) {
    // normal initialization code follows
})

我的第一次尝试是:

function factory(fn) {
  return function() {
    if ( !(this instanceof arguments.callee) ) {
      return new arguments.callee.apply(this, arguments);
    }
    fn.apply(this, arguments);
  }
}

但失败并显示“Function.prototype.apply called on incompatible [object Object]”。第二次尝试是:

function factory(fn) {
  return function() {
    if ( !(this instanceof arguments.callee) ) {
      var tmp = new arguments.callee();
      arguments.callee.apply(tmp, arguments);
      return tmp;
    }
    fn.apply(this, arguments);
  }
}

这种方法可行,但它可能会调用包装函数两次:一次不带参数(创建新实例),一次带参数进行实际初始化。显然这是脆弱且低效的,但我无法想出一种方法来通过一次调用来完成。这可能吗?

编辑:基于 bobince 的方法,这是一个类似的方法:

function factory(init) {
    var run_init = true;
    function constr() {
        if ( !(this instanceof constr) ) {
            run_init = false;
            var tmp = new constr();
            run_init = true;
            init.apply(tmp, arguments);
            return tmp;
        }
    if (run_init)
        init.apply(this, arguments);
  }
  return constr;
}

至于这是否应该被鼓励,这是值得商榷的。我来自 Python 背景,我认为 new 只是噪音 (Java) 或疣 (Javascript),但我可能遗漏了一些东西。

最佳答案

这只会助长一种捷径的坏习惯,即过于依赖类的实现来“修复”调用代码。

如果这是一个问题,不要让它滑动,抛出错误消息。

关于javascript - 删除对 "new"的需要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1977629/

相关文章:

javascript - 查找所有选中的复选框和单选按钮

javascript - 从 NPM 安装 CRA 和 NextJS 时出现问题(错误 : Couldn't find package "@babel/core" on "npm" registry)

javascript - 鼠标移出时淡出,除非在设定时间内鼠标悬停

c# - 我可以在构造函数调用中将对象的状态设置为对象本身吗?

c++ - C++ 隐式复制和移动构造函数背后的基本原理?

.net - 试图理解 F# 类定义语法

C# 现有对象上的 'new' 关键字

c++ - 如何在 C++ 中将指向变量的指针声明为函数的参数?

c# - 有什么理由不使用 `new object().foo()` 吗?

javascript - Lodash 深度过滤器和映射嵌套对象