您好,登錄后才能下訂單哦!
如何分析javascript作用域和作用域鏈,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
1、最外層函數(shù)和最外層函數(shù)定義的變量 var age = 20 function func1() { var sex = "男" function func2() { console.log("hello func2") } func2() } console.log(age) //20 console.log(func1) //正常執(zhí)行 console.log(func2) //報錯 console.log(sex) //報錯
2、所有未直接聲明的變量,直接賦值為全局變量 function func1() { var age = 20 sex = "男" } func1() console.log(sex) //男 console.log(age) //報錯
3、window對象上面的屬性具有全局作用域 function func1() { var age = 20 sex = "男" console.log(top) //window.... } func1() console.log(sex) //"男" console.log(top) //window....
和全局作用域相反,局部作用域只在函數(shù)內部可以訪問到。function func1() { var age = 20 func1() function func1() { console.log("func1") }}func1()和全局作用域相反,局部作用域只在函數(shù)內部可以訪問到。 function func1() { var age = 20 func1() function func1() { console.log("func1") } } func1()
函數(shù)也是對象,在函數(shù)內部存在一個屬性[[scope]],該屬性包含可以訪問屬性的集合。決定了哪些屬性在函數(shù)中可以訪問到。
下面我們以一個函數(shù)的例子來詳細解說一下,函數(shù)作用域鏈。 1、在函數(shù)函數(shù)創(chuàng)建出來時。代碼如下所示 function add(num1, num2) { return num1 + num2 }
函數(shù)初始化時,會將自己的作用域鏈中放入全局變量
var total = add(10, 20) 這里是函數(shù)執(zhí)行時,當執(zhí)行時會創(chuàng)建一個新的對象放入作用域鏈中,這個對象中包括 arguments, 形參,this,以及返回值。
active object是活躍對象,是函數(shù)執(zhí)行時創(chuàng)建的對象,然后scope chain類似于棧結構,函數(shù)執(zhí)行前壓入棧中,函數(shù)執(zhí)行結束就從棧中彈出。函數(shù)訪問屬性的過程就是沿著scope chain從上往下一次查找。
從上面的例子中,我們可以看出,訪問全局作用域是最慢的,因為需要依次從上往下進行查找,應當盡可能少的使用全局變量,應該盡可能使用局部變量。如果在函數(shù) 中,使用多次全局變量,我們可以將全局變量轉化為局部變量,然后在使用局部變量。
function changeColor(){ document.getElementById("btnChange").onclick=function(){ document.getElementById("targetCanvas").style.backgroundColor="red"; }; } 上面代碼我們使用了兩次document,但是document作為全局變量,此時我們應該將其轉化為局部變量來使用,所以下面為轉化后的代碼。 function changeColor(){ var doc=document; doc.getElementById("btnChange").onclick=function(){ doc.getElementById("targetCanvas").style.backgroundColor="red"; }; }
with語法的作用就是為了解決代碼重寫問題,是對象快捷書寫方式,但是這么好的方式,為什么不大力推廣使用呢?因為性能存在一些問題。function initUI(){ with(document){ var bd=body, links=getElementsByTagName("a"), i=0, len=links.length; while(i < len){ update(links[i++]); } getElementById("btnInit").onclick=function(){ doSomething(); }; }}這里使用with語法省略了document。with語法的作用就是為了解決代碼重寫問題,是對象快捷書寫方式,但是這么好的方式,為什么不大力推廣使用呢? 因為性能存在一些問題。 function initUI(){ with(document){ var bd=body, links=getElementsByTagName("a"), i=0, len=links.length; while(i < len){ update(links[i++]); } getElementById("btnInit").onclick=function(){ doSomething(); }; } } 這里使用with語法省略了document。
with傳入的對象的屬性放入最上層,剩余的都往下壓,導致局部變量的訪問代價增大,所以with的性能不好。
我們在使用try--catch時,當代碼執(zhí)行錯誤時,會執(zhí)行catch函數(shù),catch函數(shù)中參數(shù)是錯誤對象,就是這個錯誤對象,會放到作用域鏈的頭部。 但是try--catch我們在必要的使用得使用,我們可以這樣解決。 try{ doSomething(); }catch(ex){ alert(ex.message); //作用域鏈在此處改變 } 處理后: try{ doSomething(); }catch(ex){ handleError(ex); //委托給處理器方法 } 解決方案是:將catch錯誤處理交給另外一個函數(shù)進行處理。
javascript是一種動態(tài)類型、弱類型的語言,基于對象和事件驅動并具有相對安全性并廣泛用于客戶端網(wǎng)頁開發(fā)的腳本語言,同時也是一種廣泛用于客戶端Web開發(fā)的腳本語言。它主要用來給HTML網(wǎng)頁添加動態(tài)功能,現(xiàn)在JavaScript也可被用于網(wǎng)絡服務器,如Node.js。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。