函數(shù)是 JavaScript 中的基本組件之一。 一個函數(shù)是 JavaScript 過程 — 一組執(zhí)行任務(wù)或計算值的語句。要使用一個函數(shù),你必須將其定義在你希望調(diào)用它的作用域內(nèi)。
一個JavaScript 函數(shù)用function關(guān)鍵字定義,后面跟著函數(shù)名和圓括號。
定義函數(shù)
函數(shù)聲明
一個函數(shù)定義(也稱為函數(shù)聲明,或函數(shù)語句)由一系列的function關(guān)鍵字組成,依次為:
- 函數(shù)的名稱。
- 函數(shù)參數(shù)列表,包圍在括號中并由逗號分隔。
- 定義函數(shù)的 JavaScript 語句,用大括號
{}括起來。
例如,以下的代碼定義了一個簡單的square函數(shù):
function square(number) {
return number * number;
}
函數(shù)square使用了一個參數(shù),叫作number。這個函數(shù)只有一個語句,它說明該函數(shù)將函數(shù)的參數(shù)(即number)自乘后返回。函數(shù)的return語句確定了函數(shù)的返回值:
return number * number;
原始參數(shù)(比如一個具體的數(shù)字)被作為值傳遞給函數(shù);值被傳遞給函數(shù),如果被調(diào)用函數(shù)改變了這個參數(shù)的值,這樣的改變不會影響到全局或調(diào)用函數(shù)。
如果你傳遞一個對象(即一個非原始值,例如Array或用戶自定義的對象)作為參數(shù),而函數(shù)改變了這個對象的屬性,這樣的改變對函數(shù)外部是可見的,如下面的例子所示:
function myFunc(theObject) {
theObject.make = "Toyota";
}
var mycar = {make: "Honda", model: "Accord", year: 1998};
var x, y;
x = mycar.make; // x獲取的值為 "Honda"
myFunc(mycar);
y = mycar.make; // y獲取的值為 "Toyota"
// (make屬性被函數(shù)改變了)
函數(shù)表達式
雖然上面的函數(shù)聲明在語法上是一個語句,但函數(shù)也可以由函數(shù)表達式創(chuàng)建。這樣的函數(shù)可以是匿名的;它不必有一個名稱。例如,函數(shù)square也可這樣來定義:
var square = function(number) { return number * number; };
var x = square(4); // x gets the value 16
然而,函數(shù)表達式也可以提供函數(shù)名,并且可以用于在函數(shù)內(nèi)部代指其本身,或者在調(diào)試器堆棧跟蹤中識別該函數(shù):
var factorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};
console.log(factorial(3));
當將函數(shù)作為參數(shù)傳遞給另一個函數(shù)時,函數(shù)表達式很方便。下面的例子演示了一個叫map的函數(shù)如何被定義,而后使用一個表達式函數(shù)作為其第一個參數(shù)進行調(diào)用:
function map(f,a) {
var result = [],i; //創(chuàng)建一個新數(shù)組
for (i = 0; i != a.length; i++)
result[i] = f(a[i]);
return result;
}
下面的代碼:
function map(f, a) {
var result = []; // 創(chuàng)建一個數(shù)組
var i; // 聲明一個值,用來循環(huán)
for (i = 0; i != a.length; i++)
result[i] = f(a[i]);
return result;
}
var f = function(x) {
return x * x * x;
}
var numbers = [0,1, 2, 5,10];
var cube = map(f,numbers);
console.log(cube);
返回 [0, 1, 8, 125, 1000]。
在 JavaScript 中,可以根據(jù)條件來定義一個函數(shù)。比如下面的代碼,當num 等于 0 的時候才會定義 myFunc :
var myFunc;
if (num == 0){
myFunc = function(theObject) {
theObject.make = "Toyota"
}
}
除了上述的定義函數(shù)方法外,你也可以在運行時用 Function 構(gòu)造器由一個字符串來創(chuàng)建一個函數(shù) ,很像 eval() 函數(shù)。
當一個函數(shù)是一個對象的屬性時,稱之為方法。了解更多關(guān)于對象和方法的知識 使用對象。
調(diào)用函數(shù)
定義一個函數(shù)并不會自動的執(zhí)行它。定義了函數(shù)僅僅是賦予函數(shù)以名稱并明確函數(shù)被調(diào)用時該做些什么。調(diào)用函數(shù)才會以給定的參數(shù)真正執(zhí)行這些動作。例如,一旦你定義了函數(shù)square,你可以如下這樣調(diào)用它:
square(5);
上述語句通過提供參數(shù) 5 來調(diào)用函數(shù)。函數(shù)執(zhí)行完它的語句會返回值25。
函數(shù)一定要處于調(diào)用它們的域中,但是函數(shù)的聲明可以被提升(出現(xiàn)在調(diào)用語句之后),如下例:
console.log(square(5));
/* ... */
function square(n) { return n*n }
函數(shù)域是指函數(shù)聲明時的所在的地方,或者函數(shù)在頂層被聲明時指整個程序。
提示:注意只有使用如上的語法形式(即 function funcName(){})才可以。而下面的代碼是無效的。就是說,函數(shù)提升僅適用于函數(shù)聲明,而不適用于函數(shù)表達式。
console.log(square); // square is hoisted with an initial value undefined.
console.log(square(5)); // TypeError: square is not a function
var square = function (n) {
return n * n;
}
函數(shù)的參數(shù)并不局限于字符串或數(shù)字。你也可以將整個對象傳遞給函數(shù)。函數(shù) show_props(其定義參見 用對象編程)就是一個將對象作為參數(shù)的例子。
函數(shù)可以被遞歸,就是說函數(shù)可以調(diào)用其本身。例如,下面這個函數(shù)就是用遞歸計算階乘:
function factorial(n){
if ((n == 0) || (n == 1))
return 1;
else
return (n * factorial(n - 1));
}
你可以計算1-5的階乘如下:
var a, b, c, d, e;
a = factorial(1); // 1賦值給a
b = factorial(2); // 2賦值給b
c = factorial(3); // 6賦值給c
d = factorial(4); // 24賦值給d
e = factorial(5); // 120賦值給e
還有其它的方式來調(diào)用函數(shù)。常見的一些情形是某些地方需要動態(tài)調(diào)用函數(shù),或者函數(shù)的實參數(shù)量是變化的,或者調(diào)用函數(shù)的上下文需要指定為在運行時確定的特定對象。顯然,函數(shù)本身就是對象,因此這些對象也有方法(參考Function )。作為此中情形之一,apply()方法可以實現(xiàn)這些目的。
函數(shù)作用域節(jié)
在函數(shù)內(nèi)定義的變量不能在函數(shù)之外的任何地方訪問,因為變量僅僅在該函數(shù)的域的內(nèi)部有定義。相對應(yīng)的,一個函數(shù)可以訪問定義在其范圍內(nèi)的任何變量和函數(shù)。換言之,定義在全局域中的函數(shù)可以訪問所有定義在全局域中的變量。在另一個函數(shù)中定義的函數(shù)也可以訪問在其父函數(shù)中定義的所有變量和父函數(shù)有權(quán)訪問的任何其他變量。
// 下面的變量定義在全局作用域(global scope)中
var num1 = 20,
num2 = 3,
name = "Chamahk";
// 本函數(shù)定義在全局作用域
function multiply() {
return num1 * num2;
}
multiply(); // 返回 60
// 嵌套函數(shù)的例子
function getScore() {
var num1 = 2,
num2 = 3;
function add() {
return name + " scored " + (num1 + num2);
}
return add();
}
getScore(); // 返回 "Chamahk scored 5"
作用域和函數(shù)堆棧
遞歸
一個函數(shù)可以指向并調(diào)用自身。有三種方法可以達到這個目的:
- 函數(shù)名
[arguments.callee](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)- 作用域下的一個指向該函數(shù)的變量名
例如,思考一下如下的函數(shù)定義:
var foo = function bar() {
// statements go here
};
在這個函數(shù)體內(nèi),以下的語句是等價的:
bar()arguments.callee()foo()
調(diào)用自身的函數(shù)我們稱之為遞歸函數(shù)。在某種意義上說,遞歸近似于循環(huán)。兩者都重復(fù)執(zhí)行相同的代碼,并且兩者都需要一個終止條件(避免無限循環(huán)或者無限遞歸)。例如以下的循環(huán):
var x = 0;
while (x < 10) { // "x < 10" 是循環(huán)條件
// do stuff
x++;
}
可以被轉(zhuǎn)化成一個遞歸函數(shù)和對其的調(diào)用:
function loop(x) {
if (x >= 10) // "x >= 10" 是退出條件(等同于 "!(x < 10)")
return;
// 做些什么
loop(x + 1); // 遞歸調(diào)用
}
loop(0);
不過,有些算法并不能簡單的用迭代來實現(xiàn)。例如,獲取樹結(jié)構(gòu)中所有的節(jié)點時,使用遞歸實現(xiàn)要容易得多:
function walkTree(node) {
if (node == null) //
return;
// do something with node
for (var i = 0; i < node.childNodes.length; i++) {
walkTree(node.childNodes[i]);
}
}
跟loop函數(shù)相比,這里每個遞歸調(diào)用都產(chǎn)生了更多的遞歸。
將遞歸算法轉(zhuǎn)換為非遞歸算法是可能的,不過邏輯上通常會更加復(fù)雜,而且需要使用堆棧。事實上,遞歸函數(shù)就使用了堆棧:函數(shù)堆棧。
這種類似堆棧的行為可以在下例中看到:
function foo(i) {
if (i < 0)
return;
console.log('begin:' + i);
foo(i - 1);
console.log('end:' + i);
}
foo(3);
// 輸出:
// begin:3
// begin:2
// begin:1
// begin:0
// end:0
// end:1
// end:2
// end:3
嵌套函數(shù)和閉包
你可以在一個函數(shù)里面嵌套另外一個函數(shù)。嵌套(內(nèi)部)函數(shù)對其容器(外部)函數(shù)是私有的。它自身也形成了一個閉包。一個閉包是一個可以自己擁有獨立的環(huán)境與變量的的表達式(通常是函數(shù))。
既然嵌套函數(shù)是一個閉包,就意味著一個嵌套函數(shù)可以”繼承“容器函數(shù)的參數(shù)和變量。換句話說,內(nèi)部函數(shù)包含外部函數(shù)的作用域。
可以總結(jié)如下:
- 內(nèi)部函數(shù)只可以在外部函數(shù)中訪問。
- 內(nèi)部函數(shù)形成了一個閉包:它可以訪問外部函數(shù)的參數(shù)和變量,但是外部函數(shù)卻不能使用它的參數(shù)和變量。
下面的例子展示了嵌套函數(shù):
function addSquares(a, b) {
function square(x) {
return x * x;
}
return square(a) + square(b);
}
a = addSquares(2, 3); // returns 13
b = addSquares(3, 4); // returns 25
c = addSquares(4, 5); // returns 41
由于內(nèi)部函數(shù)形成了閉包,因此你可以調(diào)用外部函數(shù)并為外部函數(shù)和內(nèi)部函數(shù)指定參數(shù):
function outside(x) {
function inside(y) {
return x + y;
}
return inside;
}
fn_inside = outside(3); // Think of it like: give me a function that adds 3 to whatever you give it
result = fn_inside(5); // returns 8
result1 = outside(3)(5); // returns 8
保存變量
注意到上例中 inside 被返回時 x 是怎么被保留下來的。一個閉包必須保存它可見作用域中所有參數(shù)和變量。因為每一次調(diào)用傳入的參數(shù)都可能不同,每一次對外部函數(shù)的調(diào)用實際上重新創(chuàng)建了一遍這個閉包。只有當返回的 inside 沒有再被引用時,內(nèi)存才會被釋放。
這與在其他對象中存儲引用沒什么不同,但是通常不太明顯,因為并不能直接設(shè)置引用,也不能檢查它們。
多層嵌套函數(shù)
函數(shù)可以被多層嵌套。例如,函數(shù)A可以包含函數(shù)B,函數(shù)B可以再包含函數(shù)C。B和C都形成了閉包,所以B可以訪問A,C可以訪問B和A。因此,閉包可以包含多個作用域;他們遞歸式的包含了所有包含它的函數(shù)作用域。這個稱之為作用域鏈。(稍后會詳細解釋)
思考一下下面的例子:
function A(x) {
function B(y) {
function C(z) {
console.log(x + y + z);
}
C(3);
}
B(2);
}
A(1); // logs 6 (1 + 2 + 3)
在這個例子里面,C可以訪問B的y和A的x。這是因為:
- B形成了一個包含A的閉包,B可以訪問A的參數(shù)和變量
- C形成了一個包含B的閉包
- B包含A,所以C也包含A,C可以訪問B和A的參數(shù)和變量。換言之,C用這個順序鏈接了B和A的作用域
反過來卻不是這樣。A不能訪問C,因為A看不到B中的參數(shù)和變量,C是B中的一個變量,所以C是B私有的。
命名沖突
當同一個閉包作用域下兩個參數(shù)或者變量同名時,就會產(chǎn)生命名沖突。更近的作用域有更高的優(yōu)先權(quán),所以最近的優(yōu)先級最高,最遠的優(yōu)先級最低。這就是作用域鏈。鏈的第一個元素就是最里面的作用域,最后一個元素便是最外層的作用域。
看以下的例子:
function outside() {
var x = 5;
function inside(x) {
return x * 2;
}
return inside;
}
outside()(10); // returns 20 instead of 10
命名沖突發(fā)生在return x上,inside的參數(shù)x和outside變量x發(fā)生了沖突。這里的作用鏈域是{inside, outside, 全局對象}。因此inside的x具有最高優(yōu)先權(quán),返回了20(inside的x)而不是10(outside的x)。
閉包
閉包是 JavaScript 中最強大的特性之一。JavaScript 允許函數(shù)嵌套,并且內(nèi)部函數(shù)可以訪問定義在外部函數(shù)中的所有變量和函數(shù),以及外部函數(shù)能訪問的所有變量和函數(shù)。但是,外部函數(shù)卻不能夠訪問定義在內(nèi)部函數(shù)中的變量和函數(shù)。這給內(nèi)部函數(shù)的變量提供了一定的安全性。此外,由于內(nèi)部函數(shù)可以訪問外部函數(shù)的作用域,因此當內(nèi)部函數(shù)生存周期大于外部函數(shù)時,外部函數(shù)中定義的變量和函數(shù)將的生存周期比內(nèi)部函數(shù)執(zhí)行時間長。當內(nèi)部函數(shù)以某一種方式被任何一個外部函數(shù)作用域訪問時,一個閉包就產(chǎn)生了。
var pet = function(name) { //外部函數(shù)定義了一個變量"name"
var getName = function() {
//內(nèi)部函數(shù)可以訪問 外部函數(shù)定義的"name"
return name;
}
//返回這個內(nèi)部函數(shù),從而將其暴露在外部函數(shù)作用域
return getName;
};
myPet = pet("Vivie");
myPet(); // 返回結(jié)果 "Vivie"
實際上可能會比上面的代碼復(fù)雜的多。在下面這種情形中,返回了一個包含可以操作外部函數(shù)的內(nèi)部變量方法的對象。
var createPet = function(name) {
var sex;
return {
setName: function(newName) {
name = newName;
},
getName: function() {
return name;
},
getSex: function() {
return sex;
},
setSex: function(newSex) {
if(typeof newSex == "string"
&& (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
sex = newSex;
}
}
}
}
var pet = createPet("Vivie");
pet.getName(); // Vivie
pet.setName("Oliver");
pet.setSex("male");
pet.getSex(); // male
pet.getName(); // Oliver
在上面的代碼中,外部函數(shù)的name變量對內(nèi)嵌函數(shù)來說是可取得的,而除了通過內(nèi)嵌函數(shù)本身,沒有其它任何方法可以取得內(nèi)嵌的變量。內(nèi)嵌函數(shù)的內(nèi)嵌變量就像內(nèi)嵌函數(shù)的保險柜。它們會為內(nèi)嵌函數(shù)保留“穩(wěn)定”——而又安全——的數(shù)據(jù)參與運行。而這些內(nèi)嵌函數(shù)甚至不會被分配給一個變量,或者不必一定要有名字。
var getCode = (function(){
var secureCode = "0]Eal(eh&2"; // A code we do not want outsiders to be able to modify...
return function () {
return secureCode;
};
})();
getCode(); // Returns the secret code
盡管有上述優(yōu)點,使用閉包時仍然要小心避免一些陷阱。如果一個閉包的函數(shù)用外部函數(shù)的變量名定義了同樣的變量,那在外部函數(shù)域?qū)⒃僖矡o法指向該變量。
var createPet = function(name) { // Outer function defines a variable called "name"
return {
setName: function(name) { // Enclosed function also defines a variable called "name"
name = name; // ??? How do we access the "name" defined by the outer function ???
}
}
}
使用 arguments 對象
函數(shù)的實際參數(shù)會被保存在一個類似數(shù)組的arguments對象中。在函數(shù)內(nèi),你可以按如下方式找出傳入的參數(shù):
arguments[i]
其中i是參數(shù)的序數(shù)編號(譯注:數(shù)組索引),以0開始。所以第一個傳來的參數(shù)會是arguments[0]。參數(shù)的數(shù)量由arguments.length表示。
使用arguments對象,你可以處理比聲明的更多的參數(shù)來調(diào)用函數(shù)。這在你事先不知道會需要將多少參數(shù)傳遞給函數(shù)時十分有用。你可以用arguments.length來獲得實際傳遞給函數(shù)的參數(shù)的數(shù)量,然后用arguments對象來取得每個參數(shù)。
例如,設(shè)想有一個用來連接字符串的函數(shù)。唯一事先確定的參數(shù)是在連接后的字符串中用來分隔各個連接部分的字符(譯注:比如例子里的分號“;”)。該函數(shù)定義如下:
function myConcat(separator) {
var result = ''; // 把值初始化成一個字符串,這樣就可以用來保存字符串了??!
var i;
// iterate through arguments
for (i = 1; i < arguments.length; i++) {
result += arguments[i] + separator;
}
return result;
}
你可以給這個函數(shù)傳遞任意數(shù)量的參數(shù),它會將各個參數(shù)連接成一個字符串“列表”:
// returns "red, orange, blue, "
myConcat(", ", "red", "orange", "blue");
// returns "elephant; giraffe; lion; cheetah; "
myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
// returns "sage. basil. oregano. pepper. parsley. "
myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
提示:arguments變量只是 ”類數(shù)組對象“,并不是一個數(shù)組。稱其為類數(shù)組對象是說它有一個索引編號和length屬性。盡管如此,它并不擁有全部的Array對象的操作方法。
更多信息請閱讀JavaScript參考里的Function一文。
函數(shù)參數(shù)
從ECMAScript 6開始,有兩個新的類型的參數(shù):默認參數(shù),剩余參數(shù)。
默認參數(shù)
在JavaScript中,函數(shù)參數(shù)的默認值是undefined。然而,在某些情況下設(shè)置不同的默認值是有用的。這時默認參數(shù)可以提供幫助。
在過去,用于設(shè)定默認的一般策略是在函數(shù)的主體測試參數(shù)值是否為undefined,如果是則賦予一個值。如果在下面的例子中,調(diào)用函數(shù)時沒有實參傳遞給b,那么它的值就是undefined,于是計算a*b得到、函數(shù)返回的是 NaN:
function multiply(a, b) {
b = (typeof b !== 'undefined') ? b : 1;
return a*b;
}
multiply(5); // 5
使用默認參數(shù),在函數(shù)體的檢查就不再需要了?,F(xiàn)在,你可以在函數(shù)頭簡單地把1設(shè)定為b的默認值:
function multiply(a, b = 1) {
return a*b;
}
multiply(5); // 5
了解更多默認參數(shù)的信息。
剩余參數(shù)
剩余參數(shù)語法允許將不確定數(shù)量的參數(shù)表示為數(shù)組。在下面的例子中,使用剩余參數(shù)收集從第二個到最后參數(shù)。然后,我們將這個數(shù)組的每一個數(shù)與第一個參數(shù)相乘。這個例子是使用了一個箭頭函數(shù),這將在下一節(jié)介紹。
function multiply(multiplier, ...theArgs) {
return theArgs.map(x => multiplier * x);
}
var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]
箭頭函數(shù)
箭頭函數(shù)表達式(也稱胖箭頭函數(shù))相比函數(shù)表達式具有較短的語法并以詞法的方式綁定 this。箭頭函數(shù)總是匿名的。另見 hacks.mozilla.org 的博文:“深度了解ES6:箭頭函數(shù)”。
有兩個因素會影響引入箭頭函數(shù):更簡潔的函數(shù)和 this。
更簡潔的函數(shù)
有一些函數(shù)模式,更簡潔的函數(shù)很受歡迎。對比一下:
var a = [
"Hydrogen",
"Helium",
"Lithium",
"Beryllium"
];
var a2 = a.map(function(s){ return s.length });
console.log(a2); // logs [ 8, 6, 7, 9 ]
var a3 = a.map( s => s.length );
console.log(a3); // logs [ 8, 6, 7, 9 ]
this 的詞法
在箭頭函數(shù)出現(xiàn)之前,每一個新函數(shù)都重新定義了自己的 this 值(在嚴格模式下,一個新的對象在構(gòu)造函數(shù)里是未定義的,以“對象方法”的方式調(diào)用的函數(shù)是上下文對象等)。以面向?qū)ο蟮木幊田L(fēng)格,這樣著實有點惱人。
function Person() {
// The Person() constructor defines `this` as itself.
this.age = 0;
setInterval(function growUp() {
// In nonstrict mode, the growUp() function defines `this`
// as the global object, which is different from the `this`
// defined by the Person() constructor.
this.age++;
}, 1000);
}
var p = new Person();
在ECMAScript 3/5里,通過把this的值賦值給一個變量可以修復(fù)這個問題。
function Person() {
var self = this; // Some choose `that` instead of `self`.
// Choose one and be consistent.
self.age = 0;
setInterval(function growUp() {
// The callback refers to the `self` variable of which
// the value is the expected object.
self.age++;
}, 1000);
}
另外,創(chuàng)建一個約束函數(shù)可以使得 this值被正確傳遞給 growUp() 函數(shù)。
箭頭函數(shù)捕捉閉包上下文的this值,所以下面的代碼工作正常。
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
預(yù)定義函數(shù)
JavaScript語言有好些個頂級的內(nèi)建函數(shù):
<dl style="font-style: normal; margin: 0px 0px 20px; padding: 0px; border: 0px; box-sizing: border-box; max-width: 42rem; color: rgb(51, 51, 51); font-family: Arial, x-locale-body, sans-serif; font-size: 16px; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: -0.04448px; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`eval()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval "執(zhí)行指定代碼之后的返回值。如果返回值為空,返回undefined")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**eval()**`方法會對一串字符串形式的JavaScript代碼字符求值。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`uneval()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/uneval "uneval() 函數(shù)創(chuàng)建一個代表對象的源代碼的字符串。") </dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**uneval()**`方法創(chuàng)建的一個[`Object`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object "Object 構(gòu)造函數(shù)創(chuàng)建一個對象包裝器。")的源代碼的字符串表示。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`isFinite()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isFinite "該全局 isFinite() 函數(shù)用來判斷被傳入的參數(shù)值是否為一個有限數(shù)值(finite number)。在必要情況下,參數(shù)會首先轉(zhuǎn)為一個數(shù)值。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**isFinite()**`函數(shù)判斷傳入的值是否是有限的數(shù)值。 如果需要的話,其參數(shù)首先被轉(zhuǎn)換為一個數(shù)值。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`isNaN()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isNaN "isNaN() 函數(shù)用來確定一個值是否為NaN 。注:isNaN函數(shù)內(nèi)包含一些非常有趣的規(guī)則;你也可以通過ECMAScript 2015/ES6 中定義的Number.isNaN()或者 可以使用typeof 來判斷該值是否為一個非數(shù)字。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**isNaN()**`函數(shù)判斷一個值是否是[`NaN`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NaN "全局屬性 NaN 的值表示不是一個數(shù)字(Not-A-Number)。")。注意:`isNaN`函數(shù)內(nèi)部的`[強制轉(zhuǎn)換規(guī)則](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isNaN#Description)`十分有趣; 另一個可供選擇的是ECMAScript 6 中定義[`Number.isNaN()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN "Number.isNaN() 方法確定傳遞的值是否為 NaN和其類型是 Number。它是原始的全局isNaN()的更強大的版本。") , 或者使用 `[typeof](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/typeof)`來判斷數(shù)值類型。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`parseFloat()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseFloat "parseFloat() 函數(shù)解析一個字符串參數(shù)并返回一個浮點數(shù)。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**parseFloat()**` 函數(shù)解析字符串參數(shù),并返回一個浮點數(shù)。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`parseInt()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseInt "parseInt() 函數(shù)解析一個字符串參數(shù),并返回一個指定基數(shù)的整數(shù) (數(shù)學(xué)系統(tǒng)的基礎(chǔ))。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**parseInt()**` 函數(shù)解析字符串參數(shù),并返回指定的基數(shù)(基礎(chǔ)數(shù)學(xué)中的數(shù)制)的整數(shù)。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`decodeURI()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURI "decodeURI() 函數(shù)解碼一個由encodeURI 先前創(chuàng)建的統(tǒng)一資源標識符(URI)或類似的例程。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**decodeURI()**` 函數(shù)對先前經(jīng)過[`encodeURI`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURI "encodeURI() 函數(shù)通過將特定字符的每個實例替換為一個、兩個、三或四轉(zhuǎn)義序列來對統(tǒng)一資源標識符 (URI) 進行編碼 (該字符的 UTF-8 編碼僅為四轉(zhuǎn)義序列)由兩個 "代理" 字符組成)。")函數(shù)或者其他類似方法編碼過的字符串進行解碼。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`decodeURIComponent()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent "decodeURIComponent() 方法用于解碼由 encodeURIComponent 方法或者其它類似方法編碼的部分統(tǒng)一資源標識符(URI)。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**decodeURIComponent()**`方法對先前經(jīng)過[`encodeURIComponent`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent "encodeURIComponent()是對統(tǒng)一資源標識符(URI)的組成部分進行編碼的方法。它使用一到四個轉(zhuǎn)義序列來表示字符串中的每個字符的UTF-8編碼(只有由兩個Unicode代理區(qū)字符組成的字符才用四個轉(zhuǎn)義字符編碼)。")函數(shù)或者其他類似方法編碼過的字符串進行解碼。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`encodeURI()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURI "encodeURI() 函數(shù)通過將特定字符的每個實例替換為一個、兩個、三或四轉(zhuǎn)義序列來對統(tǒng)一資源標識符 (URI) 進行編碼 (該字符的 UTF-8 編碼僅為四轉(zhuǎn)義序列)由兩個 "代理" 字符組成)。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**encodeURI()**`方法通過用以一個,兩個,三個或四個轉(zhuǎn)義序列表示字符的UTF-8編碼替換統(tǒng)一資源標識符(URI)的某些字符來進行編碼(每個字符對應(yīng)四個轉(zhuǎn)義序列,這四個序列組了兩個”替代“字符)。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`encodeURIComponent()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent "encodeURIComponent()是對統(tǒng)一資源標識符(URI)的組成部分進行編碼的方法。它使用一到四個轉(zhuǎn)義序列來表示字符串中的每個字符的UTF-8編碼(只有由兩個Unicode代理區(qū)字符組成的字符才用四個轉(zhuǎn)義字符編碼)。")</dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
`**encodeURIComponent()**` 方法通過用以一個,兩個,三個或四個轉(zhuǎn)義序列表示字符的UTF-8編碼替換統(tǒng)一資源標識符(URI)的每個字符來進行編碼(每個字符對應(yīng)四個轉(zhuǎn)義序列,這四個序列組了兩個”替代“字符)。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`escape()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/escape "廢棄的 escape() 方法生成新的由十六進制轉(zhuǎn)義序列替換的字符串. 使用 encodeURI 或 encodeURIComponent 代替.") </dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
已廢棄的 `**escape()**` 方法計算生成一個新的字符串,其中的某些字符已被替換為十六進制轉(zhuǎn)義序列。使用 [`encodeURI`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURI "encodeURI() 函數(shù)通過將特定字符的每個實例替換為一個、兩個、三或四轉(zhuǎn)義序列來對統(tǒng)一資源標識符 (URI) 進行編碼 (該字符的 UTF-8 編碼僅為四轉(zhuǎn)義序列)由兩個 "代理" 字符組成)。")或者[`encodeURIComponent`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent "encodeURIComponent()是對統(tǒng)一資源標識符(URI)的組成部分進行編碼的方法。它使用一到四個轉(zhuǎn)義序列來表示字符串中的每個字符的UTF-8編碼(只有由兩個Unicode代理區(qū)字符組成的字符才用四個轉(zhuǎn)義字符編碼)。")替代本方法。
</dd>
<dt style="font-style: normal; margin: 0px; padding: 0px; border: 0px; font-weight: 700;">[`unescape()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/unescape "已廢棄的unescape() 方法計算生成一個新的字符串,其中的十六進制轉(zhuǎn)義序列將被其表示的字符替換。上述的轉(zhuǎn)義序列就像escape里介紹的一樣。因為 unescape 已經(jīng)廢棄,建議使用 decodeURI或者decodeURIComponent 替代本方法。") </dt>
<dd style="font-style: normal !important; margin: 0px 0px 24px; padding: 0px 0px 0px 20px; border: 0px;">
已廢棄的 `**unescape()**` 方法計算生成一個新的字符串,其中的十六進制轉(zhuǎn)義序列將被其表示的字符替換。上述的轉(zhuǎn)義序列就像[`escape`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/escape "廢棄的 escape() 方法生成新的由十六進制轉(zhuǎn)義序列替換的字符串. 使用 encodeURI 或 encodeURIComponent 代替.")里介紹的一樣。因為 `unescape` 已經(jīng)廢棄,建議使用[`decodeURI()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURI "decodeURI() 函數(shù)解碼一個由encodeURI 先前創(chuàng)建的統(tǒng)一資源標識符(URI)或類似的例程。")或者[`decodeURIComponent`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent "decodeURIComponent() 方法用于解碼由 encodeURIComponent 方法或者其它類似方法編碼的部分統(tǒng)一資源標識符(URI)。") 替代本方法。
</dd>
</dl>