js中 (function(){xxx})(); 的意思

segmentfault上的问题
自执行匿名函数:

  • 常见格式:(function() { /* code */ })();
  • 解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。
  • 作用:可以用它创建命名空间,只要把自己所有的代码都写在这个特殊的函数包装内,那么外部就不能访问,除非你允许(变量前加上window,这样该函数或变量就成为全局)。各JavaScript库的代码也基本是这种组织形式。

总结一下,执行函数的作用主要为 匿名自动执行,代码在被解释时就已经在运行了。

  1. 使这段代码被载入时候自动执行。
  2. 避免污染全局变量。

其他写法:

1.(function () { /* code */ } ()); 
2.!function () { /* code */ } ();
3.~function () { /* code */ } ();
4.-function () { /* code */ } ();
5.+function () { /* code */ } ();

来源:诺和人家30问,处理音频时,下面是子杰的源码

1.var AudioControl = (function() {
2. var myAudio = $("#myAudio").get(0);
3. function setAudioSrc(source) {
4. myAudio.src = source;
5. }
6. function play() {
7. myAudio.play();
8. }
9. function pause() {
10. myAudio.pause();
11. }
12. function stop() {
13. myAudio.pause();
14. myAudio.currentTime = 0;
15. }
16. return {
17. setAudioSrc: setAudioSrc,
18. play: play,
19. pause: pause,
20. stop: stop
21. }
22. })();
23.// 调用
24.AudioControl.setAudioSrc($p.attr("data-audio"));
25.AudioControl.play();

js中函数的几种定义方式

W3Schools: JavaScript Function Definitions

1. Function Declarations (函数声明)

Earlier in this tutorial, you learned that functions are declared with the following syntax:

1.function functionName(parameters) {
2. code to be executed
3.}

Declared functions are not executed immediately. They are “saved for later use”, and will be executed later, when they are invoked (called upon).
声明的函数不会立即被执行,它们会被“保存为以后的使用”,并且将会在他们被调用时执行。

Semicolons are used to separate executable JavaScript statements.
Since a function declaration is not an executable statement, it is not common to end it with a semicolon.
分号用来执行可执行的javascript语句,因为函数声明不是一个可执行语句,所以它的结束不用分号。

2. Function Expressions (函数表达式)

A JavaScript function can also be defined using an expression.
A function expression can be stored in a variable:
一个函数也可以用表达式来定义,一个函数表达式可以被储存在一个变量中。

1.var x = function (a, b) {return a * b};
2.var z = x(4, 3);

The function above is actually an anonymous function (a function without a name).
Functions stored in variables do not need function names. They are always invoked (called) using the variable name.
上面的函数实际上是一个匿名函数
储存在变量中的函数不需要函数名,他们总是用变量名被调用。

The function above ends with a semicolon because it is a part of an executable statement.
这个函数用分号结束因为它是可执行语句的一部分。

3. The Function() Constructor (Function()构造函数)

As you have seen in the previous examples, JavaScript functions are defined with the function keyword.
Functions can also be defined with a built-in JavaScript function constructor called Function().
就像是在前面的例子中看到的,javascript的函数使用function关键字定义的。
函数还可以用javascript的一个内置构造函数定义叫Function()。

1.var myFunction = new Function("a", "b", "return a * b");
2.var x = myFunction(4, 3);

You actually don’t have to use the function constructor.
你实际上不需要构造函数(用函数表达式一样可以)。

Most of the time, you can avoid using the new keyword in JavaScript.
大多数时候,在javascript中你要避免使用new关键字。

4. Function Hoisting (函数提升?)

scoping(作用域)
hoisting(变量提升)
expressions (表达式)

Earlier in this tutorial, you learned about “hoisting”.
Hoisting is JavaScript’s default behavior of moving declarations to the top of the current scope.
Hoisting applies to variable declarations and to function declarations.
Because of this, JavaScript functions can be called before they are declared:

在这个教程的早期,你学到了变量提升。
变量提升是javascript的默认行为:将声明提升到当前作用域的顶端。
变量提升用在变量定义和函数的声明。
正因为如此 ,javascript的函数可以在声明之前被调用。

1.myFunction(5);
2.function myFunction(y) {
3. return y * y;
4.}

Functions defined using an expression are not hoisted.
使用函数表达式定义的函数不会被变量提升。

5. Self-Invoking Functions (自调用函数)

Function expressions can be made “self-invoking”.
A self-invoking expression is invoked (started) automatically, without being called.
Function expressions will execute automatically if the expression is followed by ().
You cannot self-invoke a function declaration.
You have to add parentheses around the function to indicate that it is a function expression:

函数表达式可以被自调用。
一个自调用的函数表达式可以被自动执行,而不是被调用。
函数表达式将被自动执行,如果表达式遵循()
不能自调用一个函数声明
你必须在函数周围添加圆括号来证明这是函数表达式

(function () { … })最外面的括号返回一个未命名的函数
随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。
作用:可以用它创建命名空间,只要把自己所有的代码都写在这个特殊的函数包装内,那么外部就不能访问,除非你允许(变量前加上window,这样该函数或变量就成为全局)。各JavaScript库的代码也基本是这种组织形式。

1.(function () {
2. var x = "Hello!!"; // I will invoke myself
3.})();

The function above is actually an anonymous self-invoking function (function without name).
上面的函数实际上是一个匿名的自调用函数。

6. Functions Can Be Used as Values (函数可以和变量一样被使用)

JavaScript functions can be used as values:

1.function myFunction(a, b) {
2. return a * b;
3.}
4.var x = myFunction(4, 3);

JavaScript functions can be used in expressions:

1.function myFunction(a, b) {
2. return a * b;
3.}
4.var x = myFunction(4, 3) * 2;

7. Functions are Objects (函数可以是对象)

The typeof operator in JavaScript returns “function” for functions.
But, JavaScript functions can best be described as objects.
JavaScript functions have both properties and methods.

在javascript中对函数用typeof运算符返回的是function
但是,javascript中的函数可以被描述为对象
javascript中的函数都有自己的属性方法

The arguments.length property returns the number of arguments received when the function was invoked:
arguments.length 返回函数在调用是的参数个数。

1.function myFunction(a, b) {
2. return arguments.length; // 2
3.}

The toString() method returns the function as a string:
toString()方法就像一个字符串一样返回一个函数

1.function myFunction(a, b) {
2. return a * b;
3.}
4.var txt = myFunction.toString(); // function myFunction(a, b) { return a * b; }

A function defined as the property of an object, is called a method to the object.
A function designed to create new objects, is called an object constructor.
函数定义为对象的属性,被调用为对象的方法。
创建新对象的函数,被称为对象构造函数。

JavaScript Hoisting (javascript变量/函数提升)

Hoisting is JavaScript’s default behavior of moving declarations to the top.
提升是javascript的默认行为,将声明提升到顶部。

JavaScript Declarations are Hoisted

In JavaScript, a variable can be declared after it has been used.
In other words; a variable can be used before it has been declared.
在javascript中,一个变量可以在声明之前被使用。

1.x = 5; // Assign 5 to x
2.elem = document.getElementById("demo"); // Find an element
3.elem.innerHTML = x; // Display x in the element
4.var x; // Declare x

Hoisting is JavaScript’s default behavior of moving all declarations to the top of the current scope (to the top of the current script or the current function).
提升是将所有声明提到当前作用域顶部的默认行为(提升到当前脚本或当前函数的顶部)

JavaScript Initializations are Not Hoisted

JavaScript only hoists declarations, not initializations.
javascript只会提升声明,不会提升初始化。
Example 1 does not give the same result as Example 2:

1.// Example1
2.var x = 5; // Initialize x
3.var y = 7; // Initialize y
4.elem = document.getElementById("demo"); // Find an element
5.elem.innerHTML = x + " " + y; // Display x and y
6.// 5,7
1.// Example2
2.var x = 5; // Initialize x
3.elem = document.getElementById("demo"); // Find an element
4.elem.innerHTML = x + " " + y; // Display x and y
5.var y = 7; // Initialize y
6.// 5,undefined

Does it make sense that y is undefined in the last example?
This is because only the declaration (var y), not the initialization (=7) is hoisted to the top.
Because of hoisting, y has been declared before it is used, but because initializations are not hoisted, the value of y is undefined.
最后一个例子中y是undefined。
这是因为只有y的声明(var y)被提升到了顶部,而不是它的初始化(=7)
因为提升,y在使用之前被声明,但是因为初始化不会被提升,所以y的值是undefined。

Example 2 is the same as writing:

1.var x = 5; // Initialize x
2.var y; // Declare y
3.
4.elem = document.getElementById("demo"); // Find an element
5.elem.innerHTML = x + " " + y; // Display x and y
6.
7.y = 7; // Assign 7 to y

Declare Your Variables At the Top !

Hoisting is (to many developers) an unknown or overlooked behavior of JavaScript.
If a developer doesn’t understand hoisting, programs may contain bugs (errors).
To avoid bugs, always declare all variables at the beginning of every scope.
Since this is how JavaScript interprets the code, it is always a good rule.
提升对于许多开发者来说是一个未知或忽视的javascript行为
如果不理解提升,可能会造成错误。
去避免错误,在每一个作用域的顶部声明变量
因为这是javascript解释代码的方式。

JavaScript in strict mode does not allow variables to be used if they are not declared.
Study “use strict” in the next chapter.
javascript的严格模式不允许使用未声明的变量。

JavaScript Scope (作用域)

JavaScript Scope

In JavaScript, objects and functions are also variables.
In JavaScript, scope is the set of variables, objects, and functions you have access to.
JavaScript has function scope: The scope changes inside functions.

在javascript中,对象和函数也是变量。
在javascript中,作用域是变量,对象的集合,你可以访问函数。(?)
javascript有函数作用域,作用域在函数内部变化。

Local JavaScript Variables (局部变量)

Variables declared within a JavaScript function, become LOCAL to the function.
Local variables have local scope: They can only be accessed within the function.

在函数内部声明的变量,对于函数来说是本地的。
局部变量有局部的作用域,它们只能在函数内部被访问。

1.// code here can not use carName
2.
3.function myFunction() {
4. var carName = "Volvo";
5.
6. // code here can use carName
7.
8.}

Since local variables are only recognized inside their functions, variables with the same name can be used in different functions.
Local variables are created when a function starts, and deleted when the function is completed.

因为局部变量只能在它们的函数内部被识别,所以在不同函数中可以使用相同名字的变量。
局部变量在函数开始时产生,在函数结束时被删除。

Global JavaScript Variables (全局变量)

A variable declared outside a function, becomes GLOBAL.
A global variable has global scope: All scripts and functions on a web page can access it.
一个变量在函数之外被声明,就变为全局的。
一个全局变量具有全局作用域,所有的脚本和函数都可以访问它。

1.var carName = " Volvo";
2.
3.// code here can use carName
4.
5.function myFunction() {
6.
7. // code here can use carName
8.
9.}

Automatically Global (自动转化为全局)

If you assign a value to a variable that has not been declared, it will automatically become a GLOBAL variable.
This code example will declare carName as a global variable, even if it is executed inside a function.
如果你将值付给一个未被声明的变量,它将自动被转换为全局变量。
下面的例子在将会声明 carName 为全局变量,即使它在一个函数中被执行。

1.// code here can use carName
2.
3.function myFunction() {
4. carName = "Volvo";
5.
6. // code here can use carName
7.
8.}

The Lifetime of JavaScript Variables (变量的生存期)

The lifetime of a JavaScript variable starts when it is declared.
Local variables are deleted when the function is completed.
Global variables are deleted when you close the page.

一个变量的生存期在它被声明时开始。
局部变量在函数完成时结束。
全局变量在页面被关闭时结束。

Function Arguments (函数参数)

Function arguments (parameters) work as local variables inside functions.
函数的参数作为局部变量在函数中被使用。

Global Variables in HTML (HTML中的全局变量)

With JavaScript, the global scope is the complete JavaScript environment.
In HTML, the global scope is the window object: All global variables belong to the window object.

在javascript中,全局变量在完整的javascript环境。
在HTML中全局变量是window对象,所有全局变量属于window对象。

1.// code here can use window.carName
2.
3.function myFunction() {
4. carName = "Volvo";
5.}

Your global variables (or functions) can overwrite window variables (or functions).
Any function, including the window object, can overwrite your global variables and functions.
你的全局变量(函数)可以重写window变量(函数)。
任何函数,包括窗口对象,可以重写你的全局变量和函数。

JavaScript Best Practices (最佳实践)

Avoid Global Variables (避免全局变量)

Minimize the use of global variables.
This includes all data types, objects, and functions.
Global variables and functions can be overwritten by other scripts.
Use local variables instead, and learn how to use closures.

减少使用全局变量。
这包括所有的数据类型,对象和函数。
全局变量可以被其他脚本重写。
使用局部变量,并学习如何使用闭包。

Always Declare Local Variables (总是声明局部变量)

All variables used in a function should be declared as local variables.
Local variables must be declared with the var keyword, otherwise they will become global variables.

所有在函数里的变量应该都被声明为局部变量。
局部变量必须用关键字 var 声明,否则它将会变为全局变量。

Strict mode does not allow undeclared variables.
严格模式不允许使用未声明的变量。

Declarations on Top (在顶部声明)

It is a good coding practice to put all declarations at the top of each script or function.
将声明都放在脚本或函数的顶部,这是一个很棒的编码实践。
This will:

  • Give cleaner code
  • Provide a single place to look for local variables
  • Make it easier to avoid unwanted (implied) global variables
  • Reduce the possibility of unwanted re-declarations

这将会:

  • 有更整洁的代码。
  • 提供一个单一的地方去寻找局部变量。
  • 更容易避免不必要的(隐含的)全局变量。
  • 减少重复声明的可能性。
1.// Declare at the beginning
2.var firstName, lastName, price, discount, fullPrice;
3.
4.// Use later
5.firstName = "John";
6.lastName = "Doe";
7.
8.price = 19.90;
9.discount = 0.10;
10.
11.fullPrice = price * 100 / discount;

This also goes for loop variables:

1.// Declare at the beginning
2.var i;
3.
4.// Use later
5.for (i = 0; i < 5; i++) {

By default, JavaScript moves all declarations to the top (JavaScript hoisting).
默认情况下,javascript将所有的声明提升至顶部(javascript提升)

Initialize Variables

It is a good coding practice to initialize variables when you declare them.
当声明同时初始化变量
This will:

  • Give cleaner code
  • Provide a single place to initialize variables
  • Avoid undefined values
1.// Declare and initiate at the beginning
2.var firstName = "",
3. lastName = "",
4. price = 0,
5. discount = 0,
6. fullPrice = 0,
7. myArray = [],
8. myObject = {};

Initializing variables provides an idea of the intended use (and intended data type).
初始化变量提供一个使用的想法(和目标的数据类型)

Never Declare Number, String, or Boolean Objects

不要用 Number,String,Boolean 声明对象

Always treat numbers, strings, or booleans as primitive values. Not as objects.
Declaring these types as objects, slows down execution speed, and produces nasty side effects:

把numbers,strings或者 booleans 作为原始值,不要作为对象。
声明这些类型为对象,会减慢执行速度,并且产生令人厌恶的副作用。

1.var x = "John";             
2.var y = new String("John");
3.(x === y) // is false because x is a string and y is an object.

Or even worse:

1.var x = new String("John");             
2.var y = new String("John");
3.(x == y) // is false because you cannot compare objects.

Don’t Use new Object()

  • Use {} instead of new Object()
  • Use “” instead of new String()
  • Use 0 instead of new Number()
  • Use false instead of new Boolean()
  • Use [] instead of new Array()
  • Use /()/ instead of new RegExp()
  • Use function (){} instead of new function()
1.var x1 = {};           // new object
2.var x2 = ""; // new primitive string
3.var x3 = 0; // new primitive number
4.var x4 = false; // new primitive boolean
5.var x5 = []; // new array object
6.var x6 = /()/; // new regexp object
7.var x7 = function(){}; // new function object

Beware of Automatic Type Conversions (注意自动类型转换)

Beware that numbers can accidentally be converted to strings or NaN (Not a Number).
JavaScript is loosely typed. A variable can contain different data types, and a variable can change its data type:

注意number会不小心被转换为 string 或 NaN
javascript是弱类型,一个变量可以包含不同的数据类型,并且一个变量可以改变它的数据类型

1.var x = "Hello";     // typeof x is a string
2.x = 5; // changes typeof x to a number

When doing mathematical operations, JavaScript can convert numbers to strings:

1.var x = 5 + 7;       // x.valueOf() is 12,  typeof x is a number
2.var x = 5 + "7"; // x.valueOf() is 57, typeof x is a string
3.var x = "5" + 7; // x.valueOf() is 57, typeof x is a string
4.var x = 5 - 7; // x.valueOf() is -2, typeof x is a number
5.var x = 5 - "7"; // x.valueOf() is -2, typeof x is a number
6.var x = "5" - 7; // x.valueOf() is -2, typeof x is a number
7.var x = 5 - "x"; // x.valueOf() is NaN, typeof x is a number

Subtracting a string from a string, does not generate an error but returns NaN (Not a Number):

1."Hello" - "Dolly"    // returns NaN

Use === Comparison

The == comparison operator always converts (to matching types) before comparison.
The === operator forces comparison of values and type:

==运算符总是在比较之前转换(去匹配数据类型)
===运算符强迫比较值和类型。

1.0 == "";        // true
2.1 == "1"; // true
3.1 == true; // true
4.
5.0 === ""; // false
6.1 === "1"; // false
7.1 === true; // false

Use Parameter Defaults (使用参数默认值)

If a function is called with a missing argument, the value of the missing argument is set to undefined.
Undefined values can break your code. It is a good habit to assign default values to arguments.

如果函数在调用时少一个参数,这个丢失的参数的值被定义为undefined
未定义的值会破坏你的代码,分配给参数默认值是一个很好的习惯。

1.function myFunction(x, y) {
2. if (y === undefined) {
3. y = 0;
4. }
5.}

End Your Switches with Defaults (用Defaults结束Switch)

Always end your switch statements with a default. Even if you think there is no need for it.
总是用default结束switch,即使你认为没有必要。

1.switch (new Date().getDay()) {
2. case 0:
3. day = "Sunday";
4. break;
5. case 1:
6. day = "Monday";
7. break;
8. case 2:
9. day = "Tuesday";
10. break;
11. case 3:
12. day = "Wednesday";
13. break;
14. case 4:
15. day = "Thursday";
16. break;
17. case 5:
18. day = "Friday";
19. break;
20. case 6:
21. day = "Saturday";
22. break;
23. default:
24. day = "Unknown";
25.}

Avoid Using eval()

The eval() function is used to run text as code. In almost all cases, it should not be necessary to use it.
Because it allows arbitrary code to be run, it also represents a security problem.

不要使用eval()
因为它允许任意代码运行,它也会造成安全问题。