JS解惑-(fun)()表达式的含义
JS中经常能看到 (function(){...})(),那么双括号()到底是什么意思呢?
背景
我们先来看看一些实际工作中用到的()的例子。
形式是这样的:
(function(){
//TODO
})();
当然在jquery中,有时候为了避免变量$冲突,也经常这么用:
jQuery.noConflict();
(function($){
//TODO
})(jQuery);
分析
引自 Ecma-262 第 12.2.10.4章节 的语句:
ParenthesizedExpression : ( Expression )
1. Return the result of evaluating Expression. This may be of type Reference.
我个人的理解翻译:
圆括号括起来的表达式:(表达式)
返回计算表达式的结果,这可能是一个引用。
返回计算表达式的结果
这句话怎么理解呢?举个例子:
(function(){
console.log(123456);
});
打印结果就是这个function的函数表达式,即:
function(){
console.log(123456);
}
如果上面的例子,后面再加一个(),那么就是立即执行这个函数,即:
(function(){
console.log(123456);
})();
结果:123456
引申:
写到这里大家可能会问,为什么要这么用呢?
2个作用:
- 立即执行函数,即:self-executing function
- 构建独立不受污染的块级作用域
关于立即执行函数,参考我之前写过的一片文章:
另外,我们知道JS在ES6之前是没有块级作用域的,那么通过这种 (匿名函数) 的形式,可以保证 () 函数中拥有独立的作用域,而外部无法访问。
什么是块级作用域? 即,在一些类似于C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的。 出自《JavaScript 权威指南》中
3.10.1章节,即57页
比如:
for(var i=0;i<10;i++){
//TODO
};
console.log(i);
结果为:10,也就是说,你在for中定义的变量i,在for结束后依然生效。
这可能是一个引用
这句话怎么理解呢?举个例子:
var obj = {
name : 'night',
sayHi : function(){
console.log('hello ' + this.name);
}
};
(obj);
结果就是这个obj的对象本身(也就定义中说的,是对obj的引用):
Object {name: "night"}
name:"night"
sayHi:()
__proto__:Object
既然是这样,那么以下语句结果就不言而喻了吧:
(obj.sayHi)();//hello night
//注意:(obj.sayHi())(),是不正确的哦!!!
//因为(obj.sayHi)本身就返回了一个引用对象,不能在()里面直接就运行哦,那你要两个()就没用了。
我还是分析下吧:
- (obj) = obj;//即,对obj的引用
- (obj.sayHi) = obj.sayHi();//即,调用对象自己的sayHi方法
引申:
JavaScript 高级程序设计(第三版) 的 7.2.2 关于this对象 中有个例子,看了以上概念,大家肯定更好理解了。
例子在这本书的 183页 最终结果:My Object,大家自己去看。
结论
(expression) 的理解:
- 返回计算表达式的结果
- 还可能返回的是一个引用
(expression)() 的作用:
- 立即执行函数
- 构建独立不受污染的作用域