JavaScript 中带有小写“f”的 `new function()`

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2274695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:34:15  来源:igfitidea点击:

`new function()` with lower case "f" in JavaScript

javascriptfunctionobjectinstantiation

提问by Johnny Oshika

My colleague has been using "new function()" with a lower case "f" to define new objects in JavaScript. It seems to work well in all major browsers and it also seems to be fairly effective at hiding private variables. Here's an example:

我的同事一直在使用带有小写“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;
        };
    };

As soon as "this" is used, it becomes a public property of someObj. So someObj.foo, someObj.get_inner() and someObj.set_inner() are all available publicly. In addition, set_inner() and get_inner() are privileged methods, so they have access to "inner" through closures.

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

However, I haven't seen any reference to this technique anywhere. Even Douglas Crockford's JSLint complains about it:

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

  • weird construction. Delete 'new'
  • 奇怪的建筑。删除“新”

We're using this technique in production and it seems to be working well, but I'm a bit anxious about it because it's not documented anywhere. Does anyone know if this is a valid technique?

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

采纳答案by CMS

I've seen that technique before, it's valid, you are using a function expression as if it were a Constructor Function.

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

But IMHO, you can achieve the same with an auto-invoking function expression, I don't really see the point of using the newoperator in that way:

但是恕我直言,您可以使用自动调用函数表达式实现相同的目的,我真的不明白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;
})();

The purpose of the newoperator is to create new object instances, setting up the [[Prototype]]internal property, you can see how this is made by the [Construct]internal property.

new操作符的目的是创建新的对象实例,设置[[Prototype]]内部属性,你可以看到这是如何通过[Construct]内部属性实现的。

The above code will produce an equivalent result.

上面的代码将产生等效的结果。

回答by kennytm

Your code is just similar to the less weird construct

您的代码与不那么奇怪的构造相似

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

    ...
};
var someObj = new Foo;

回答by DUzun

To clarify some aspects and make Douglas Crockford's JSLint not to complain about your code here are some examples of instantiation:

为了澄清某些方面并使 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

In example 3. expression in (...) as value is a function/constructor. It looks like this: new (function (){...})(). So if we omit ending brackets as in example 2, the expression is still a valid constructor call and looks like example 4.

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

Douglas Crockford's JSLint "thinks" you wanted to assign the function to someObj, not its instance. And after all it's just an warning, not an error.

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