在JavaScript中使用小写"f"的`new function()`

Joh*_*ika 106 javascript function object instantiation

我的同事一直在使用带有小写"f"的"new function()"来定义JavaScript中的新对象.它似乎在所有主流浏览器中运行良好,并且在隐藏私有变量方面似乎也相当有效.这是一个例子:

    var someObj = new function () {
        var inner = 'some value';
        this.foo = 'blah';

        this.get_inner = function () {
            return inner;
        };

        this.set_inner = function (s) {
            inner = s;
        };
    };
Run Code Online (Sandbox Code Playgroud)

一旦使用"this",它就成为someObj的公共财产.所以someObj.foo,someObj.get_inner()和someObj.set_inner()都是公开的.另外,set_inner()和get_inner()是特权方法,因此它们可以通过闭包访问"内部".

但是,我在任何地方都没有看到任何对此技术的引用.甚至Douglas Crockford的JSLint抱怨它:

  • 怪异的建筑.删除'新'

我们在生产中使用这种技术,它似乎运作良好,但我有点担心它,因为它没有在任何地方记录.有谁知道这是否是一种有效的技术?

CMS*_*CMS 64

我以前见过这种技术,它是有效的,你使用的是函数表达式,就好像它是一个构造函数.

但是恕我直言,你可以用自动调用函数表达式实现相同的功能,我真的没有看到new以这种方式使用运算符的意义:

var someObj = (function () {
    var instance = {},
        inner = 'some value';

    instance.foo = 'blah';

    instance.get_inner = function () {
        return inner;
    };

    instance.set_inner = function (s) {
        inner = s;
    };

    return instance;
})();
Run Code Online (Sandbox Code Playgroud)

new运算符的目的是创建新的对象实例,设置[[Prototype]]内部属性,您可以看到内部属性是如何创建的[Construct].

上面的代码将产生相同的结果.

  • 我想你最后错过了一个`return instance;`.否则,`someObj`将只是'undefined`.:-) (3认同)

ken*_*ytm 15

您的代码与较不奇怪的构造类似

function Foo () {
    var inner = 'some value';
    this.foo = 'blah';

    ...
};
var someObj = new Foo;
Run Code Online (Sandbox Code Playgroud)

  • 它不仅仅是相似的,它完全相同的东西......唯一的例外是它们无法重用Foo来创建另一个对象. (9认同)
  • OP的版本可以通过**new someObj.constructor**重用.这里构造函数显式地添加到命名空间中; 正确的风格取决于功能的预期目的.此外,这种风格 - 虽然肯定是标准 - 允许有人填充全局命名空间,如果他们在**Foo**之前忘记**新**. (3认同)

DUz*_*zun 12

为了澄清某些方面并让Douglas Crockford的JSLint不要抱怨你的代码,这里有一些实例化的例子:

1. o = new Object(); // normal call of a constructor

2. o = new Object;   // accepted call of a constructor

3. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
})(); // normal call of a constructor

4. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
}); // accepted call of a constructor
Run Code Online (Sandbox Code Playgroud)

在示例3中,(...)中的表达式作为值是函数/构造函数.它看起来像这样:new(function(){...})().因此,如果我们省略示例2中的结束括号,则表达式仍然是有效的构造函数调用,看起来像示例4.

Douglas Crockford的JSLint"认为"你想将函数分配给someObj,而不是它的实例.毕竟这只是一个警告,而不是一个错误.