让我们反汇编这段代码。
首先有一个带有立即调用的匿名函数。它类似于:
(function () {/**/}).call();
(new Date()).getTime(); // timestamp since 1970 jan 1 in milliseconds
我们不分配new Date()
给变量,而是立即使用它。
现在为什么要使用.call
而不是 just ()
?
.call
是一种方法Functions
都有。第一个参数是this
绑定的对象,后续参数将作为参数传递给函数。所以:
(function () {
console.log(this.foo); // bar
}).call({ "foo": "bar" });
这与undefined
(见下文)结合使用。
.call
与一个微小的区别相同。只需要 2 个参数,其中第二个是参数数组。这将是类似的:.apply
.apply
(function () {}).call(this, "foo", "bar");
(function () {}).apply(this, [ "foo", "bar" ]);
apply 的一个常见用途是与魔法变量结合使用arguments
。
(function () {
console.log(Array.prototype.slice.call(arguments, 1)); // [ "bar" ]
})([ "foo", "bar" ]);
Array.prototype.slice.call(arguments, 1)
可能看起来很吓人,但实际上它只是arguments.slice(1)
,但arguments
不是,Array
所以它没有slice
功能。我们借用Array
sslice
函数并使用.call
来设置this
to arguments
。Array.prototype.slice(arguments, 1??)
是不正确的。
现在为什么在this
里面.call(this)
?this
总是指向您所在的上下文。如果您在一个类的实例中,它将指向该实例,如果您在全局范围内,它将指向该实例。在浏览器环境中也是window
.
为什么undefined
?由于我们.call(this)
没有第二个参数,所以匿名函数的所有参数都是undefined
. 我不太确定为什么需要在此处创建一个显式变量undefined
。也许这是对某些浏览器或某些喜欢undefined
定义的 lint 工具的支持。
感谢@TedHopp。undefined
善变。
var undefined = "foo";
console.log(undefined); // undefined
(function (undefined) {
console.log(undefined); // "foo"
})("foo");
您可以轻松拥有:
(function () {
/* code here */
}());
这是完全有效的,并且工作方式相同。使用您发布的表单可能会有一些性能或 linting 好处。