請寫出彈出值,并解釋為什么。
~function () {
alert(a);
a();
var a = function () {
console.log(1);
}
function a() {
console.log(2);
}
alert(a)
a();
var c = d = a;
}();
alert(d);
alert(c); 詞法分析:
0:函數(shù)的在運行的瞬間,生成一個活動對象(Active Object)就是所謂的AO
1:分析參數(shù)
1-1:函數(shù)接收參數(shù),添加到AO的屬性上面,值全部都是undefine,如AO.age=undefine
1-2:接收實參,形成AO對應(yīng)的屬性值
2:分析變量聲明,如var age,
2-1:如果AO上還沒有age屬性,則添加AO 屬性,值是undefine
2-2:如果AO 上面已經(jīng)有了age屬性,則不做任何操作。
3:分析函數(shù)的聲明,例如funcion a(){},
3-1: 則把函數(shù)賦給AO.a,如果數(shù)據(jù)屬性已經(jīng)存在,則要被現(xiàn)在的新的值覆蓋
4:執(zhí)行 (賦值操作是執(zhí)行中的過程);
放在這道題里就是:
分析參數(shù):
即時函數(shù)沒有參數(shù);
分析變量:
函數(shù)內(nèi)部 AO= {a:undifined,c:undefined} 全局 AO= {c:undefined}
分析函數(shù)的聲明:
function a() {console.log(2);}
因為AO中已經(jīng)存在a,a被覆蓋為function a() {console.log(2);}
執(zhí)行:
alert(a);//a就是函數(shù)聲明 function a() {console.log(2);}
a();//執(zhí)行a -->2
var a = function () {console.log(1);} a被賦值為新函數(shù)
function a() {console.log(2);} //已經(jīng)分析過跳過
alert(a) // 彈出a 為新賦值的 function () {console.log(1);}
a(); 執(zhí)行a 打印 1
var c = d = a; // c d 賦值為function () {console.log(1);}
即時函數(shù)執(zhí)行完,向下執(zhí)行
alert(d); //作用域中有d 為function () {console.log(1);}
alert(c); //作用域中沒有c 報錯c is not defined
中間那段代碼等同于如下
function a() {
console.log(2);
}
var a;
alert(a);
a();
a = function () {
console.log(1);
}
alert(a)
a();
var c = d = a;
首先了解變量提升和函數(shù)聲明提升
則
function a() {
console.log(2);
}是函數(shù)聲明,會提升到代碼頂部
從上到下依次順序:
1.彈出
function a() {
console.log(2);
}
2.后臺打印出:
2
3:彈出
function () {
console.log(1);
}
4.后臺打印出
1
5,6.都彈出
function () {
console.log(1);
}
主要考點就是函數(shù)和變量聲明的提升順序
~function () {
alert(a) //function a(){ //coding }
a();//console.log(2)
var a = function () {
console.log(1);
}
function a() {
console.log(2);
}
alert(a)//a = function () { //coding }
a();//console.log(1)
var c = d = a;
}();
alert(d);//a = function () { //coding } d為全局變量
alert(c) //ReferenceError: c is not defined c是局部變量關(guān)于這段代碼,我關(guān)注兩個問題:
1、alert 出什么?
2、對于
~function () {
function code
}();
這段語句為何能作為函數(shù)執(zhí)行起來?
問題一的話,上面幾位朋友說得很清楚,關(guān)于問題二就是通過 ~ ! || 等操作符使得解釋器將函數(shù)聲明能當(dāng)做表達(dá)式來處理。
詳見這里描述得很詳細(xì)
包括打印和alert的值如下:
1、
function a() {
console.log(2);
}
2、2
3、
function a() {
console.log(1);
}
4、1
5、
function a() {
console.log(1);
}
原因: var c = d = a;從右向左執(zhí)行,d=a,d沒有使用var聲明,是一個全局變量,方法外部可訪問。
6、報錯,原因:c是函數(shù)內(nèi)部的變量,外部訪問不到的,外部變量c是undefined。
其它的就不一一解釋原因了,本質(zhì)就是變量提升和函數(shù)聲明提升的問題。
實際上,這段代碼是這么跑的:
~function () {
//hoisting
function a() {
console.log(2);
}
var a;
alert(a);
a();
a = function () {
console.log(1);
}
alert(a)
a();
d = a;
var c = d;
}();
alert(d);
alert(c);
參考:hoisting
這個問題其實是考你對JS預(yù)解析和閉包的理解,
function () {
alert(a); // 因為JS是單線程,而前面沒有聲明a所以這里報錯
a(); //這里也會報錯因為也沒有聲明
var a = function () { // 這里是一個函數(shù)表達(dá)式
console.log(1);
}
function a() { // 這里是聲明一個函數(shù)
console.log(2)
}
alert(a) // 這里會打印一個函數(shù),因為var聲明的a被function聲明的a函數(shù)層疊掉了
a(); // 這里當(dāng)然是函數(shù)調(diào)用 打印2
var c = d = a; // 這里切記 并不是 var a , b ,c ; 所有d沒有聲明
}(); //這是一個閉包也是一個自調(diào)用函數(shù)
alert(d); //這里會報錯
alert(c); // 這里會彈出一個函數(shù)體
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進“中國制造2025”,實現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。