我的同事一直在使用带有小写“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”,它就成为someObj的公共财产。所以someObj.foo,someObj.get_inner()和someObj.set_inner()都是公开的。另外,set_inner()和get_inner()是特权方法,因此它们可以通过闭包访问“内部”。
但是,我在任何地方都没有看到任何对此技术的引用。甚至道格拉斯克罗克福德的JSLint抱怨它:
- 怪异的建筑。删除'新'
我们在生产中使用这种技术,它似乎运作良好,但我有点担心它,因为它没有在任何地方记录。有谁知道这是否是一种有效的技术?
答案 0 :(得分:64)
之前我见过这种技术,它是有效的,你使用的函数表达式好像是Constructor Function。
但是恕我直言,你可以用自动调用函数表达式实现相同的功能,我真的没有看到以这种方式使用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;
})();
new
运算符的目的是创建新的对象实例,设置[[Prototype]]
内部属性,您可以看到[Construct]
内部属性是如何做出的。
以上代码将产生相同的结果。
答案 1 :(得分:15)
您的代码与不太奇怪的构造
类似function Foo () {
var inner = 'some value';
this.foo = 'blah';
...
};
var someObj = new Foo;
答案 2 :(得分: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
在示例3中,(...)中的表达式作为值是函数/构造函数。它看起来像这样: new(function(){...})()。因此,如果我们省略示例2中的结束括号,则表达式仍然是有效的构造函数调用,看起来像示例4。
道格拉斯·克罗克福德的JSLint“认为”你想把这个函数分配给someObj,而不是它的实例。毕竟这只是一个警告,而不是错误。