详细研究过Javascript代码库(如Jquery、YUI)的人,一定会看到过很多如下形式的函数: (function(){...}()) 或 (function(){})()
对于很多初学者来说,遇到它们经常会产生一系列问号:这是编程吗,用它做什么,怎么我没在其他语言里见过呢?
接下来我就详细地解释一下:
它可以解释成为“匿名函数自调用”,也就是说,定义一个匿名函数,然后马上调用它(因为它是匿名的,如果不立即调用就获取不到该函数的引用了)。通常它被应用在一些大型的JS框架中(如上面所说的),因为这个匿名函数的函数体相当于提供一个匿名的名字空间,这样就不会再与用户自定义的JS函数、变量、对象发生冲突了。尽管JS没有显示地提供命名空间的定义和使用机制,但这种匿名方式却不失为是一种很好的解决命名空间问题的方法。
所以说,(function(){代码})()就等于执行了一个函数,只不过它是匿名的而已。如果在这个匿名函数内部想再次调用这个函数,就需要调用constructor属性了(这是Object中定义的,JS的继承机制如同Java一样保证了了所有对象都继承Object类)。
明白了它是什么了,下面我们就要学习该怎样使用它了,以下这些问题是我们会经常遇到的,不如提前做好理论只是准备以备后期能顺利地实现开发。请看下面问题:
1、下列哪些正确?(B、C)
A.function(){
alert("Here!");
}();
B.(function(){
alert("Here!");
})();
C.(function(){
alert("Here!");
}());
2、下列哪个结果是正确的?(A、B、C、D)
A.(function(a1,a2){
alert("Here!"+(a1+a2));
})(1,2);
B.(function(a1,a2){
alert("Here!" +(a1+a2));
}(1,2));
C.void function(a1,a2){
alert("Here!" +(a1+a2));
}(1,2);
D.var f = function(a1,a2){
alert("Here!" +(a1+a2));
}(1,2);
注:A 、B、C与D四种格式都正确,前两者属于同种情况的不同写法,后两种是将函数对象的返回值赋给其他变量,C是忽略函数返回值,而D正相反!
具体举个例子:
function test(){
return (function(p1,p2){
return p1+p2;
})(1,2);
};
(function(){
alert(test());
}());
下面我们就深入研究一下这种匿名函数:
1、
①
function Foo() {
var a = 123;
this.a = 456;
(function() {
alert(a); // 123
alert(this.a); // undefined
})();
};
var f = new Foo();
②
function Foo() {
var a = 123;
this.a = 456;
(function(_this) {
alert(a); // 123
alert(_this.a); // 456
})(this);
};
var f = new Foo();
以上两个对比,说明:
(1)匿名函数可以直接访问到外层署名函数(Foo)中的变量(使用关键字var定义的),但不能访问外层署名函数的属性(使用关键字this定义的);
(2)匿名函数中的this指向的是匿名函数对象的地址,它与外层署名函数(Foo)对象的this指向的地址不同;
(3)匿名函数若要访问外层署名函数(Foo)中的属性,可以通过参数传递的方式实现。
2、
①
function Foo() {
var a = 123;
this.a = 456;
(function(b) {
alert(a); // 123
alert(b); // 456
})(this.a);
};
var f = new Foo();
②
(function() {
var a = 123;
this.a = 456;
(function() {
alert(a); // 123
alert(this.a); // 456
})();
})();
以上两个对比,说明:
(1) 匿名函数既可以直接访问外层匿名函数中的变量,又直接可以访问外层匿名函数中的属性,而匿名函数却不可以直接访问外层已命名函数中的属性;
(2)以上两种方式可以实现相同的功能。
3、
①
(function() {
var a = 123;
this.a = 456;
(function() {
alert(a); // 123
alert(this.a); // 456
this.b = 789;
})();
(function() {
alert(this.b); // 789
})();
})();
(function() {
alert(this.a); // 456
alert(this.b); // 789
})();
②
function Foo() {
var a = 123;
this.a = 456;
(function() {
alert(a); // 123
alert(this.a); // undefined
this.b = 789;
})();
(function() {
alert(this.b); // 789
})();
};
var f = new Foo();
(function() {
alert(this.a); // undefined
alert(this.b); // 789
})();
以上两个对比,说明:
(1)匿名函数(即用两个小括号括起来的部分)位于一个执行上下文,不论这些代码放在哪个位置上。
4、
①
function Foo() {
(function() {
this.b = 789;
})();
(function() {
alert(this.b); // 789
alert(b); // 789
var a = 0;
alert(a); // 0
})();
}
var f = new Foo();
(function() {
alert(this.b); // 789
alert(b); // 789
})();
②
function Foo() {
(function() {
this.b = 789;
})();
(function() {
alert(this.b); // 789
alert(b); // undefined
var b = 0;
alert(b); // 0
})();
}
var f = new Foo();
(function() {
alert(this.b); // 789
alert(b); // 789
})();
以上两个对比,说明:
(1)没有加 this取值时,如果当前 {} 中不存在同名的局部变量,则等同于加 this 处理;如果当前 {} 中存在同名的局部变量,则按常规处理。
以上只是鄙人的粗浅见解,内容还不够完整,还会不断完善删改,如其中有什么错误之处还望读者谅解,真诚希望能留下您的宝贵建议,以图修改!这里欢迎每一位爱好JS的读者,真心希望能和你们交流心得!
分享到:
相关推荐
( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的,后来发现加括号的原因...
匿名函数指没有指定函数名或指针的函数,自执行匿名函数只是其中一种,下文中称这种函数为:自执行函数 下面是一个最常见的自执行函数: // 传统匿名函数 (function() { alert('hello'); })(); 这段...
匿名函数就是没有实际名字的函数。...//据说效率最高,Javascript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值。 !function(){ alert(‘!water’); }(); //运算符+匿名函数调用 (f
( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的,后来发现加括号的原因...
格式化-function与小括号间留空格。链式调用不换行 文章链接https://editor.csdn.net/md/?articleId=103597199
我最近看到很多...他们没有完全完成实现(他们在嵌套括号的末尾缺少一个().另外,由于它们在外部函数中没有做任何事情,所以嵌套的自调用函数可以刚刚嵌入到外部功能定义. 其实我不知道他们打算使用自调用函数,因
关于什么是匿名函数,及它带来的优势在本文就不深究了,先抛出一个常用的匿名函数: (function(){alert(‘yo’)})() 很多同学知道怎么用这种匿名函数,却或许并不明白为什么这样写就能够调用匿名函数。也许...
模式二:优先表达式 (Prior Expression) 由于 JavaScript 按照从内到外的顺序执行表达式,因此使用括号来强制执行已声明的函数。 代码如下: (function(){ // insert code here }()); 模式三:Void 操作符 (Void ...
解释:这是相当优雅的代码(如果你首次看见可能会一头雾水:)),包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。 来个带参数的...
代码如下: (function(){ //这里忽略jQuery所有实现 })();...当一个匿名函数被括起来,然后再在后面加一个括号,这个匿名函数就能立即运行起来!真神奇哦! 嘿嘿!胡闹到此为止。在这一节,我们碰到
该语句是由function关键字构成的,它后面紧跟的是: Ø 函数名 Ø 一个用括号的参数列表,参数是可选的,参数是用逗号分隔开 Ø 包括在大括号中的函数体 使用函数需要注意的几个地方: Ø 在函数体中如果有return...
2.当一个匿名函数被括起来,然后再在后面加一个括号,这个匿名函数就能立即运行起来!有木有很神奇哦~ 3.要使用一个函数,我们就得首先声明它的存在。而我们最常用的方式就是使用function语句来定义一个函数 4....
2.当一个匿名函数被括起来,然后再在后面加一个括号,这个匿名函数就能立即运行起来!有木有很神奇哦~ 3.要使用一个函数,我们就得首先声明它的存在。而我们最常用的方式就是使用function语句来定义一个函数 4....
在自定义函数时,即使函数的功能实现不需要设置参数,小括号“()”也不能够省略。 5.2.3 函数的参数 2、参数设置 有参函数:适用于开发时函数体内的操作需要用户传递数据的情况。 形参:指的就是形式参数,具有特定...
包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。
解释:这是相当优雅的代码(如果你首次看见可能会一头雾水:)),包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。 来个带参数的...
那么我们的问题来了,为什么要在 function () {…}() 之外用圆括号包裹呢?解答这个问题,就需要我们理解 Javascript 中函数表达式与函数声明的概念。 函数定义带来的错误 虽然 function () {…} 看上去像是一个函数...
1,JavaScript中函数、方法的调用 在JavaScript中,有两种调用函数的方式。一般的方式是把参数放在括号中,另一种方式是同时把函数和参数都放在括号中。如: 代码如下: function test(x) { alert(x); } test...
方式6,匿名函数执行放在中括号内123[function(){ console.log(this) // 浏览器得控制台输出window}(this)]
关键字function用来定义函数。...在JavaScript中,函数是Function类的具体实例。而且都与其它引用类型一样具有属性和方法。 函数名实际上是指向函数对象的指针,函数可以作为参数参与到传参和返回值中。 函数的