我想知道这是什么意思:
(function () {
})();
这是在说document。onload吗?
我想知道这是什么意思:
(function () {
})();
这是在说document。onload吗?
当前回答
这里已经有很多很好的答案了,但这里是我的2美分:p
你可以使用IIFE(立即调用函数表达式):
Avoiding pollution in the global namespace. Variables defined in IIFE (or even any normal function) don't overwrite definitions in global scope. Protecting code from being accessed by outer code. Everything that you define within the IIFE can be only be accessed within the IIFE. It protects code from being modified by outer code. Only what you explicitly return as the result of function or set as value to outer variables is accessible by outer code. Avoid naming functions that you don't need to use repeatedly. Though it's possible to use a named function in IIFE pattern you don't do it as there is no need to call it repeatedly, generally. For Universal Module Definitions which is used in many JS libraries. Check this question for details.
IIFE通常以以下方式使用:
(function(param){
//code here
})(args);
您可以省略匿名函数周围的括号(),并在匿名函数之前使用void运算符。
void function(param){
//code here
}(args);
其他回答
Normally, JavaScript code has global scope in the application. When we declare global variable in it, there is a chance for using the same duplicate variable in some other area of the development for some other purpose. Because of this duplication there may happen some error. So we can avoid this global variables by using immediately invoking function expression , this expression is self-executing expression.When we make our code inside this IIFE expression global variable will be like local scope and local variable.
我们可以通过两种方式创建IIFE
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
OR
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
在上面的代码片段中,“var app”现在是一个局部变量。
使用自调用匿名函数的原因是它们永远不应该被其他代码调用,因为它们“设置”了要调用的代码(同时为函数和变量提供了作用域)。
换句话说,它们就像在程序开始时“创建类”的程序。在它们被实例化(自动)之后,唯一可用的函数是匿名函数返回的那些函数。然而,所有其他“隐藏”函数仍然存在,以及任何状态(在作用域创建期间设置的变量)。
非常酷。
它被称为IIFE -立即调用函数表达式。下面是一个例子来展示它的语法和用法。它用于将变量的使用范围限定在函数之前,而不是超出函数。
(function () {
function Question(q,a,c) {
this.q = q;
this.a = a;
this.c = c;
}
Question.prototype.displayQuestion = function() {
console.log(this.q);
for (var i = 0; i < this.a.length; i++) {
console.log(i+": "+this.a[i]);
}
}
Question.prototype.checkAnswer = function(ans) {
if (ans===this.c) {
console.log("correct");
} else {
console.log("incorrect");
}
}
var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);
var questions = [q1, q2, q3];
var n = Math.floor(Math.random() * questions.length)
var answer = parseInt(prompt(questions[n].displayQuestion()));
questions[n].checkAnswer(answer);
})();
TL;DR:表达式可以括在圆括号中,如果函数的表达式和块形式组合在一起,则会与函数调用冲突。
我喜欢反例,因为它们描绘了一幅伟大的逻辑图景,而其他人没有列出任何反例。你可能会问,“为什么浏览器不能看到function(){}(),而只是假设它是一个表达式?”让我们用三个例子来比较这个问题。
var x; //这里fibonacci是一个block函数 函数fibonacci(x) { Var值= x < 2 ?X: fibonacci(X -1) + fibonacci(X -2); if (x === 9) console.log("The " + x + "th fibonacci is: " + value); 返回值; } (x = 9); console.log(" x的值:" + x); Console.log ("fibonacci is a(n) ")+ typeof fibonacci);
当我们将函数转换为表达式时,观察事情是如何变化的。
var x; //这里fibonacci是一个函数表达式 函数fibonacci(x) { Var值= x < 2 ?X: fibonacci(X -1) + fibonacci(X -2); if (x === 9) console.log("The " + x + "th fibonacci is: " + value); 返回值; }) (x = 9); console.log(" x的值:" + x); Console.log ("fibonacci is a(n) ")+ typeof fibonacci);
当你使用not-operator而不是圆括号时,也会发生同样的事情,因为这两个操作符都将语句转换为表达式:
var x; //这里fibonacci是一个函数表达式 ! 函数fibonacci(x) { Var值= x < 2 ?X: fibonacci(X -1) + fibonacci(X -2); if (x === 9) console.log("The " + x + "th fibonacci is: " + value); 返回值; } (x = 9); console.log(" x的值:" + x); Console.log ("fibonacci is a(n) ")+ typeof fibonacci);
通过将函数转换为表达式,它由它下面的两行(x = 9)执行。由于表达式函数和块函数的行为是分开的,所以这两个例子都运行得很好,没有歧义(规范方面)。
名字的作用域
另一个重要的观察是,命名块函数对整个作用域可见,而函数表达式只对其本身可见。换句话说,fibonacci只对第一个示例中的最后一个console.log是块时可见。在这三个例子中,fibonacci对自身是可见的,允许fibonacci调用自身,这是递归。
箭头功能
逻辑的另一个方面是箭头函数。如果块函数和表达式函数的定义合并在一起,规范将不得不包括箭头函数的任意规则和例外:
函数hello() {console.log(" hello World")} (x) => console.log("hello " + x) console.log("如果你正在阅读,没有发生错误");
虽然函数块工作正常,但函数表达式后面跟着箭头函数会产生语法错误:
! 函数hello() {console.log(" hello World")} (x) => console.log("hello " + x) console.log("如果你正在阅读,没有发生错误");
这里,第二行的(x)是调用前一行的函数还是箭头函数的函数参数是不明确的。
请注意,箭头函数多年来确实符合ECMAScript标准,在语言的初始设计中并不是一个因素;我的观点是,表达式函数和块函数之间的区别有助于JavaScript语法更有逻辑性和连贯性。
它只是一个匿名函数,在创建后立即执行。
这就像你把它赋值给一个变量,然后在后面使用它,只是没有变量:
var f = function () {
};
f();
在jQuery中,有一个类似的构造,你可能会想到:
$(function(){
});
这是绑定就绪事件的简写形式:
$(document).ready(function(){
});
但是上面的两个结构都不是iife。