JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記8 js函數(shù)(中)
(1)執(zhí)行環(huán)境(execution context):所有的JavaScript代碼都運(yùn)行在一個(gè)執(zhí)行環(huán)境中,當(dāng)控制權(quán)轉(zhuǎn)移至JavaScript的可執(zhí)行代碼時(shí),就進(jìn)入了一個(gè)執(zhí)行環(huán)境?;顒?dòng)的執(zhí)行環(huán)境從邏輯上形成了一個(gè)棧,全局執(zhí)行環(huán)境永遠(yuǎn)是這個(gè)棧的棧底元素,棧頂元素就是當(dāng)前正在運(yùn)行的執(zhí)行環(huán)境。每一個(gè)函數(shù)都有自己的執(zhí)行環(huán)境,當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí),會(huì)將這個(gè)函數(shù)的執(zhí)行環(huán)境壓入棧頂,函數(shù)執(zhí)行完之后再將這個(gè)執(zhí)行環(huán)境彈出,控制權(quán)返回給之前的執(zhí)行環(huán)境。
(2)變量對(duì)象(variable object):每一個(gè)執(zhí)行環(huán)境都有一個(gè)與之對(duì)應(yīng)的變量對(duì)象,執(zhí)行環(huán)境中定義的所有變量和函數(shù)就是保存在這個(gè)變量對(duì)象中。這個(gè)變量對(duì)象是后臺(tái)實(shí)現(xiàn)中的一個(gè)對(duì)象,我們無法在代碼中訪問,但是這有助于我們理解執(zhí)行環(huán)境和作用域相關(guān)概念。
(3)作用域鏈(scope chain):當(dāng)代碼在一個(gè)執(zhí)行環(huán)境中運(yùn)行時(shí),會(huì)創(chuàng)建由變量對(duì)象組成的一個(gè)作用域鏈。這個(gè)鏈的前端,就是當(dāng)前代碼所在環(huán)境的變量對(duì)象,鏈的最末端,就是全局環(huán)境的變量對(duì)象。在一個(gè)執(zhí)行環(huán)境中解析標(biāo)識(shí)符時(shí),會(huì)在當(dāng)前執(zhí)行環(huán)境相應(yīng)的變量對(duì)象中搜索,找到就返回,沒有找到就沿著作用域鏈一級(jí)一級(jí)往上搜索直至全局環(huán)境的變量對(duì)象,如果一直未找到,就拋出引用異常。
(4)活動(dòng)對(duì)象(activation object):如果一個(gè)執(zhí)行環(huán)境是函數(shù)執(zhí)行環(huán)境,也將變量對(duì)象稱為活動(dòng)對(duì)象。活動(dòng)對(duì)象在最開始只包含一個(gè)變量,即arguments對(duì)象(這個(gè)對(duì)象在全局環(huán)境的變量對(duì)象中不存在)。
這四個(gè)概念雖然有些抽象,但還是比較自然的,可以結(jié)合《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》中的一個(gè)例子來細(xì)細(xì)體會(huì)一下:
// 進(jìn)入到全局作用域,創(chuàng)建全局變量對(duì)象
var color = "blue";
function changeColor(){
// 進(jìn)入到changeColor作用域,創(chuàng)建changeColor相應(yīng)變量對(duì)象
var anotherColor = "red";
function swapColors(color1, color2){
// 進(jìn)入到swapColors作用域,創(chuàng)建swapColors相應(yīng)變量對(duì)象
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
/*
* swapColors作用域內(nèi)可以訪問的對(duì)象有:
* 全局變量對(duì)象的color,changeColor
* changeColor函數(shù)相應(yīng)變量對(duì)象的anotherColor、swapColors
* swapColors函數(shù)相應(yīng)變量對(duì)象的tempColor
*/
}
swapColors('white');
/*
* changeColor作用域內(nèi)可以訪問的對(duì)象有:
* 全局變量對(duì)象的color,changeColor
* changeColor函數(shù)相應(yīng)變量對(duì)象的anotherColor、swapColors
*/
}
changeColor();
/*
* 全局作用域內(nèi)可以訪問的對(duì)象有:
* 全局變量對(duì)象的color,changeColor
*/
這里的整個(gè)過程是:
(1)進(jìn)入全局環(huán)境,創(chuàng)建全局變量對(duì)象,將全局環(huán)境壓入棧頂(這里也是棧底)。根據(jù)前面的關(guān)于聲明提升的結(jié)論,這里創(chuàng)建全局變量對(duì)象可能的一個(gè)過程是,先創(chuàng)建全局變量對(duì)象,然后處理函數(shù)聲明設(shè)置屬性changeColor為相應(yīng)函數(shù),再處理變量聲明設(shè)置屬性color為undefined。
(2)執(zhí)行全局環(huán)境中的代碼。先執(zhí)行color變量初始化,賦值為'blue',再調(diào)用changeColor()函數(shù)。
(3)調(diào)用changeColor()函數(shù),進(jìn)入到changeColor函數(shù)執(zhí)行環(huán)境,創(chuàng)建這個(gè)環(huán)境相應(yīng)的變量對(duì)象(也就是活動(dòng)對(duì)象),將這個(gè)環(huán)境壓入棧頂。創(chuàng)建活動(dòng)對(duì)象可能的一個(gè)過程是,先創(chuàng)建活動(dòng)對(duì)象,處理內(nèi)部函數(shù)聲明設(shè)置屬性swapColors為相應(yīng)函數(shù),處理函數(shù)參數(shù)創(chuàng)建活動(dòng)對(duì)象的屬性arguments對(duì)象,處理內(nèi)部變量聲明設(shè)置屬性anotherColor為undefined。
(4)執(zhí)行changeColor()函數(shù)代碼。先執(zhí)行anotherColor初始化為'red',再調(diào)用swapColors()函數(shù)。
(5)調(diào)用swapColors()函數(shù),進(jìn)入到swapColors函數(shù)執(zhí)行環(huán)境,創(chuàng)建相應(yīng)的變量對(duì)象(活動(dòng)對(duì)象),將swapColors執(zhí)行環(huán)境壓入棧頂。這里創(chuàng)建活動(dòng)對(duì)象可能的一個(gè)過程是,先創(chuàng)建活動(dòng)對(duì)象,處理函數(shù)參數(shù),將形式參數(shù)作為活動(dòng)對(duì)象的屬性并賦值為undefined,創(chuàng)建活動(dòng)對(duì)象的屬性arguments對(duì)象,并根據(jù)實(shí)際參數(shù)初始化形式參數(shù)和arguments對(duì)應(yīng)的值和屬性(將屬性color1和arguments[0]初始化為'white',由于沒有第二個(gè)實(shí)際參數(shù),所以color2的值為undefined,而arguments的長度只為1了),處理完函數(shù)參數(shù)之后,再處理函數(shù)內(nèi)部變量聲明,將tempColor作為活動(dòng)對(duì)象的屬性并賦值為undefined。
(6)執(zhí)行swapColors()函數(shù)代碼。先給tempColor初始化賦值,然后實(shí)現(xiàn)值交換功能(這里color和anotherColor的值都是沿著作用域鏈才讀取到的)。
(7)swapColors()函數(shù)代碼執(zhí)行完之后,返回undefined,將相應(yīng)的執(zhí)行環(huán)境彈出棧并銷毀(注意,這里會(huì)銷毀執(zhí)行環(huán)境,但是執(zhí)行環(huán)境相應(yīng)的活動(dòng)對(duì)象并不一定會(huì)被銷毀),當(dāng)前執(zhí)行環(huán)境恢復(fù)成changeColor()函數(shù)的執(zhí)行環(huán)境。隨著swapColor()函數(shù)執(zhí)行完并返回,changeColor()也就執(zhí)行完了,同樣返回undefined,并將changeColor()函數(shù)的執(zhí)行環(huán)境彈出棧并銷毀,當(dāng)前執(zhí)行環(huán)境恢復(fù)成全局環(huán)境。整個(gè)處理過程結(jié)束,全局環(huán)境直至頁面退出再銷毀。
作用域鏈也解釋了為什么函數(shù)可以在內(nèi)部遞歸調(diào)用自身:函數(shù)名是函數(shù)定義所在執(zhí)行環(huán)境相應(yīng)變量對(duì)象的一個(gè)屬性,然后在函數(shù)內(nèi)部執(zhí)行環(huán)境中,就可以沿著作用域鏈向外上溯一層訪問函數(shù)名指向的函數(shù)對(duì)象了。如果在函數(shù)內(nèi)部將函數(shù)名指向了一個(gè)新函數(shù),遞歸調(diào)用時(shí)就會(huì)不正確了:
function fn(num){
if(1 == num){
return 1;
}else{
fn = function(){
return 0;
};
return num * fn(num - 1);
}
}
console.info(fn(5));//0
關(guān)于作用域和聲明提升,再看一個(gè)例子:
var name = 'linjisong';
function fn(){
console.info(name);//undefined
var name = 'oulinhai';
console.info(name);//oulinhai
}
fn();
console.info(name);//linjisong
這里最不直觀的可能是第3行輸出undefined,因?yàn)樵谌种幸呀?jīng)定義過name了,不過按照上面解析的步驟去解析一次,就可以得出正確的結(jié)果了。另外強(qiáng)調(diào)一下,在ECMAScript中只有全局執(zhí)行環(huán)境和函數(shù)執(zhí)行環(huán)境,相應(yīng)的也只有全局作用域和函數(shù)作用域,沒有塊作用域——雖然有塊語句。
function fn(){
var fnScope = 'a';
{
var blockScope = 'b';
blockScope += fnScope;
}
console.info(blockScope);//沒有塊作用域,所以可以在整個(gè)函數(shù)作用域內(nèi)訪問blockScope
console.info(fnScope);
}
fn();//ba,a
console.info(blockScope);//ReferenceError,函數(shù)作用域外,不能訪問內(nèi)部定義的變量
console.info(fnScope);//ReferenceError
對(duì)于作用域鏈,還可以使用with、try-catch語句的catch塊來延長:
•使用with(obj){}語句時(shí),將obj對(duì)象添加到當(dāng)前作用域鏈的最前端。
•使用try{}catch(error){}語句時(shí),將error對(duì)象添加到當(dāng)前作用域鏈的最前端。
插了一段較為抽象的概念,希望不至于影響整個(gè)閱讀的流暢,事實(shí)上,我在這里還悄悄的繞過了一個(gè)稱為“閉包”的概念,關(guān)于函數(shù)與閉包,在下篇文章中再詳細(xì)敘述。
7、函數(shù)內(nèi)部對(duì)象與this
對(duì)于面向?qū)ο笳Z言的使用者來說,this實(shí)在是再熟悉不過了,不就是指向構(gòu)造函數(shù)新創(chuàng)建的對(duì)象嗎!不過,在ECMAScript中,且別掉以輕心,事情沒有那么簡單,雖然在使用new操作符調(diào)用函數(shù)的情況下,this也的確是指向新創(chuàng)建的對(duì)象,但這只是指定this對(duì)象值的一種方式而已,還有更多的方式可以指定this對(duì)象的值,換句話說,this是動(dòng)態(tài)的,是可以由我們自己自由指定的。
(1)全局環(huán)境中的this
在全局環(huán)境中,this指向全局對(duì)象本身,在瀏覽器中也就是window,這里也可以把全局環(huán)境中的this理解為全局執(zhí)行環(huán)境相應(yīng)的變量對(duì)象,在全局環(huán)境中定義的變量和函數(shù)都是這個(gè)變量對(duì)象的屬性:
var vo = 'a';
vo2 = 'b';
function fn(){
return 'fn';
}
console.info(this === window);//true
console.info(this.vo);//a
console.info(this.vo2);//b
console.info(this.fn());//fn
如果在自定義函數(shù)中要引用全局對(duì)象,雖然可以直接使用window,但更好的方式則是將全局對(duì)象作為參數(shù)傳入函數(shù),這是在JS庫中非常通用的一種方式:
(function(global){
console.info(global === window);//在內(nèi)部可以使用global代替window了
})(this);
這種方式兼容性更好(ECMAScript的實(shí)現(xiàn)中全局對(duì)象未必都是window),在壓縮時(shí),也可以將global簡化為g,而不用使用window了。
(2)函數(shù)內(nèi)部屬性this
在函數(shù)環(huán)境中,this是一個(gè)內(nèi)部屬性對(duì)象,可以理解成函數(shù)對(duì)應(yīng)的活動(dòng)對(duì)象的一個(gè)屬性,而這個(gè)內(nèi)部屬性的值是動(dòng)態(tài)的。那this值是怎么動(dòng)態(tài)確定的呢?
•使用new調(diào)用時(shí),函數(shù)也稱為構(gòu)造函數(shù),這個(gè)時(shí)候函數(shù)內(nèi)部的this被指定為新創(chuàng)建的對(duì)象。
function fn(){
var name = 'oulinhai';//函數(shù)對(duì)應(yīng)的活動(dòng)對(duì)象的屬性
this.name = 'linjisong';//當(dāng)使用new調(diào)用函數(shù)時(shí),將this指定為新創(chuàng)建對(duì)象,也就是給新創(chuàng)建對(duì)象添加屬性
}
var person = new fn();
console.info(person.name);//linjisong
var arr = [fn];
console.info(arr[0]());//undefined
需要注意區(qū)分一下函數(shù)執(zhí)行環(huán)境中定義的屬性(也即活動(dòng)對(duì)象的屬性)和this對(duì)象的屬性,在使用數(shù)組元素方式調(diào)用函數(shù)時(shí),函數(shù)內(nèi)部this指向數(shù)組本身,因此上例最后輸出undefined。
•作為一般函數(shù)調(diào)用時(shí),this指向全局對(duì)象。
•作為對(duì)象的方法調(diào)用時(shí),this指向調(diào)用這個(gè)方法的對(duì)象。
看下面的例子:
var name = 'oulinhai';
var person = {
name:'linjisong',
getName:function(){
return this.name;
}
};
console.info(person.getName());//linjisong
var getName = person.getName;
console.info(getName());//oulinhai
這里函數(shù)對(duì)象本身是匿名的,是作為person對(duì)象的一個(gè)屬性,當(dāng)作為對(duì)象屬性調(diào)用時(shí),this指向了對(duì)象,當(dāng)把這個(gè)函數(shù)賦給另一個(gè)函數(shù)然后調(diào)用時(shí),是作為一般函數(shù)調(diào)用的,this指向了全局對(duì)象。這個(gè)例子充分說明了“函數(shù)作為對(duì)象的方法調(diào)用時(shí)內(nèi)部屬性this指向這個(gè)調(diào)用對(duì)象,函數(shù)作為一般函數(shù)調(diào)用時(shí)內(nèi)部屬性this指向全局對(duì)象”,也說明了this的指定是動(dòng)態(tài)的,是在調(diào)用時(shí)指定的,而不管函數(shù)是單獨(dú)定義的還是作為對(duì)象方法定義的。也正是因?yàn)楹瘮?shù)作為對(duì)象的方法調(diào)用時(shí)this指向這個(gè)調(diào)用對(duì)象,所以在函數(shù)內(nèi)部返回this時(shí)才能夠延續(xù)調(diào)用對(duì)象的下一個(gè)方法——也就是鏈?zhǔn)讲僮鳎╦Query的一大特色)。
•使用apply()、call()或bind()調(diào)用函數(shù)時(shí),this指向第一個(gè)參數(shù)對(duì)象。如果沒有傳入?yún)?shù)或傳入的是null和undefined,this指向全局對(duì)象(在ES5的嚴(yán)格模式下會(huì)設(shè)為null)。如果傳入的第一個(gè)參數(shù)是一個(gè)簡單類型,會(huì)將this設(shè)置為相應(yīng)的簡單類型包裝對(duì)象。
var name = 'linjisong';
function fn(){
return this.name;
}
var person = {
name:'oulinhai',
getName:fn
};
var person2 = {name:'hujinxing'};
var person3 = {name:'huanglanxue'};
console.info(fn());//linjisong,一般函數(shù)調(diào)用,內(nèi)部屬性this指向全局對(duì)象,因此this.name返回linjisong
console.info(person.getName());//oulinhai,作為對(duì)象方法調(diào)用,this指向這個(gè)對(duì)象,因此這里返回person.name
console.info(fn.apply(person2));//hujinxing,使用apply、call或bind調(diào)用函數(shù),執(zhí)行傳入的第一個(gè)參數(shù)對(duì)象,因此返回person2.name
console.info(fn.call(person2));//hujinxing
var newFn = fn.bind(person3);//ES5中新增方法,會(huì)創(chuàng)建一個(gè)新函數(shù)實(shí)例返回,內(nèi)部this值被指定為傳入的參數(shù)對(duì)象
console.info(newFn());//huanglanxue
上面示例中列出的都是一些常見情況,沒有列出第一個(gè)參數(shù)為null或undefined的情況,有興趣的朋友可以自行測試。關(guān)于this值的確定,在原書中還有一個(gè)例子:
var name = 'The Window';
var object = {
name : 'My Object',
getName:function(){
return this.name;
},
getNameFunc:function(){
return function(){
return this.name;
}
}
};
console.info(object.getName());//My Object
console.info((object.getName)());//My Object
console.info((object.getName = object.getName)());//The Window
console.info(object.getNameFunc()());//The Window
第1個(gè)是正常輸出,第2個(gè)(object.getName)與object.getName的效果是相同的,而第3個(gè)(object.getName=object.getName)最終返回的是函數(shù)對(duì)象本身,也就是說第3個(gè)會(huì)作為一般函數(shù)來調(diào)用,第4個(gè)則先是調(diào)用getNameFunc這個(gè)方法,返回一個(gè)函數(shù),然后再調(diào)用這個(gè)函數(shù),也是作為一般函數(shù)來調(diào)用。
8、函數(shù)屬性和方法
函數(shù)是一個(gè)對(duì)象,因此也可以有自己的屬性和方法。不過函數(shù)屬性和方法與函數(shù)內(nèi)部屬性很容易混淆,既然容易混淆,就把它們放一起對(duì)照著看,就好比一對(duì)雙胞胎,不對(duì)照著看,不熟悉的人是區(qū)分不了的。
先從概念上來區(qū)分一下:
(1)函數(shù)內(nèi)部屬性:可以理解為函數(shù)相應(yīng)的活動(dòng)對(duì)象的屬性,是只能從函數(shù)體內(nèi)部訪問的屬性,函數(shù)每一次被調(diào)用,都會(huì)被重新指定,具有動(dòng)態(tài)性。
(2)函數(shù)屬性和方法:這是函數(shù)作為對(duì)象所具有的特性,只要函數(shù)一定義,函數(shù)對(duì)象就被創(chuàng)建,相應(yīng)的屬性和方法就可以訪問,并且除非你在代碼中明確賦為另一個(gè)值,否則它們的值不會(huì)改變,因而具有靜態(tài)性。有一個(gè)例外屬性caller,表示調(diào)用當(dāng)前函數(shù)的函數(shù),也是在函數(shù)被調(diào)用時(shí)動(dòng)態(tài)指定,在《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》中也因此將caller屬性和函數(shù)內(nèi)部屬性arguments、this一起講解,事實(shí)上,在ES5的嚴(yán)格模式下,不能對(duì)具有動(dòng)態(tài)特性的函數(shù)屬性caller賦值。
光從概念上區(qū)分是非常抽象的,也不是那么容易理解,再把這些屬性列在一起比較一下(沒有列入一些非標(biāo)準(zhǔn)的屬性,如name):
類別 | 名稱 | 繼承性 | 說明 | 備注 |
函數(shù)內(nèi)部屬性 | this | - | 函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象 | 和一般面向?qū)ο笳Z言有很大區(qū)別 |
arguments | - |
表示函數(shù)實(shí)際參數(shù)的類數(shù)組對(duì)象 arguments本身也有自己的屬性:length、callee和caller |
1、length屬性表示實(shí)際接收到的參數(shù)個(gè)數(shù) 2、callee屬性指向函數(shù)對(duì)象本身,即有: fn.arguments.callee === fn 3、caller屬性主要和函數(shù)的caller相區(qū)分,值永遠(yuǎn)都是undefined | |
函數(shù)屬性 | caller | 否 | 調(diào)用當(dāng)前函數(shù)的函數(shù) | 雖然函數(shù)一定義就可訪問,但是不在函數(shù)體內(nèi)訪問時(shí)永遠(yuǎn)為null,在函數(shù)體內(nèi)訪問時(shí)返回調(diào)用當(dāng)前函數(shù)的函數(shù),在全局作用域中調(diào)用函數(shù)也會(huì)返回null |
length | 否 | 函數(shù)形式參數(shù)的長度 | 就是定義函數(shù)時(shí)命名的參數(shù)個(gè)數(shù) | |
prototype | 否 | 函數(shù)原型對(duì)象 | 原型對(duì)象是ECMAScript實(shí)現(xiàn)繼承的基礎(chǔ) | |
constructor | 是 | 繼承自O(shè)bject,表示創(chuàng)建函數(shù)實(shí)例的函數(shù),也就是Function() | 值永遠(yuǎn)是Function,也就是內(nèi)置的函數(shù)Function() | |
函數(shù)方法 | apply | 否 | 調(diào)用函數(shù)自身,以(類)數(shù)組方式接受參數(shù) |
這三個(gè)方法主要作用是動(dòng)態(tài)綁定函數(shù)內(nèi)部屬性this 1、apply和call在綁定之后會(huì)馬上執(zhí)行 2、bind在綁定之后可以在需要的時(shí)候再調(diào)用執(zhí)行 |
call | 否 | 調(diào)用函數(shù)自身,以列舉方式接受參數(shù) | ||
bind | 否 | 綁定函數(shù)作用域,ES5中新增 | ||
toLocalString | 覆蓋 |
覆蓋了Object類型中的方法,返回函數(shù)體 不同瀏覽器實(shí)現(xiàn)返回可能不同,可能返回原始代碼,也可能返回去掉注釋后的代碼 | ||
toString | 覆蓋 | |||
valueOf | 覆蓋 | |||
hasOwnProperty | 是 | 直接繼承自O(shè)bject類型的方法,用法同Object | ||
propertyIsEnumerable | 是 | |||
isPropertyOf | 是 |
函數(shù)屬性和方法,除了從Object繼承而來的屬性和方法,也包括函數(shù)本身特有的屬性和方法,用的最多的方法自然就是上一小節(jié)說的apply()、call(),這兩個(gè)方法都是用來設(shè)置函數(shù)內(nèi)部屬性this從而擴(kuò)展函數(shù)作用域的,只不過apply()擴(kuò)展函數(shù)作用域時(shí)是以(類)數(shù)組方式接受函數(shù)的參數(shù),而call()擴(kuò)展函數(shù)作用域時(shí)需要將函數(shù)參數(shù)一一列舉出來傳遞,看下面的例子:
function sum(){
var total = 0,
l = arguments.length ;
for(; l; l--){
total += arguments[l-1];
}
return total;
}
console.info(sum.apply(null,[1,2,3,4]));//10
console.info(sum.call(null,1,2,3,4));//10
不過需要強(qiáng)調(diào)的是:apply和call的主要作用還是在于擴(kuò)展函數(shù)作用域。apply和call在擴(kuò)展作用域時(shí)會(huì)馬上調(diào)用函數(shù),這使得應(yīng)用中有了很大限制,因此在ES5中新增加了一個(gè)bind()函數(shù),這個(gè)函數(shù)也用于擴(kuò)展作用域,但是可以不用馬上執(zhí)行函數(shù),它返回一個(gè)函數(shù)實(shí)例,將傳入給它的第一個(gè)參數(shù)作為原函數(shù)的作用域。它的一個(gè)可能的實(shí)現(xiàn)如下:
function bind(scope){
var that = this;
return function(){
that.apply(scope, arguments);
}
}
Function.prototype.bind = bind;
這里涉及了一個(gè)閉包的概念,明天再繼續(xù)。
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記13 ECMAScript5新特性
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記12 js正則表達(dá)式
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記11 內(nèi)建js對(duì)象
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記10 再訪js對(duì)象
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記9 js函數(shù)(下)
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記7 js函數(shù)(上)
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記6 初識(shí)js對(duì)象
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記5 js語句
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記4 js運(yùn)算符和操作符
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記3 js簡單數(shù)據(jù)類型
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記2 js基礎(chǔ)語法
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記 概述
相關(guān)文章
JavaScript多線程運(yùn)行庫Nexus.js詳解
這篇文章主要介紹了JavaScript多線程運(yùn)行庫Nexus.js的學(xué)習(xí)心得以及代碼分享,有需要的朋友一起參考學(xué)習(xí)下吧。2017-12-12JavaScript初學(xué)者應(yīng)注意的七個(gè)細(xì)節(jié)詳細(xì)介紹
種種語言都有它特別的地方,對(duì)于JavaScript來說,使用var就可以聲明任意類型的變量,這門腳本語言看起來很簡單,然而想要寫出優(yōu)雅的代碼卻是需要不斷積累經(jīng)驗(yàn)的,接下來介紹初學(xué)者應(yīng)注意2012-12-12分析Node.js connect ECONNREFUSED錯(cuò)誤
最近在準(zhǔn)備Angularjs +node.js demo的時(shí)候在我的mac開發(fā)中 遇見此錯(cuò)誤2013-04-04