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

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

一旦使用了“ this”,它就变成了 some Obj 的公共属性。因此,some Objec.foo、 some Objec.get _ inner ()和 some Objec.set _ inner ()都是公开可用的。另外,set _ inner ()和 get _ inner ()是有特权的方法,因此它们可以通过闭包访问“ inner”。

然而,我在任何地方都没有看到任何关于这项技术的参考,甚至道格拉斯·克罗克福特的 JSLint 也抱怨说:

  • 奇怪的结构。删除’新’

我们正在生产中使用这种技术,它似乎工作得很好,但我有点担心,因为它没有任何地方的文件。有人知道这是否是一种有效的技术吗?

32881 次浏览

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

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

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 new operator is to create new object instances, setting up the [[Prototype]] internal property, you can see how this is made by the [Construct] internal property.

The above code will produce an equivalent result.

Your code is just similar to the less weird construct

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


...
};
var someObj = new Foo;

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

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.

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.