摘要:考慮到環(huán)境導(dǎo)致的行為差異太大,應(yīng)該避免在塊級(jí)作用域內(nèi)聲明函數(shù)。函數(shù)聲明語句函數(shù)表達(dá)式循環(huán)循環(huán)還有一個(gè)特別之處,就是循環(huán)語句部分是一個(gè)父作用域,而循環(huán)體內(nèi)部是一個(gè)多帶帶的子作用域。聲明一個(gè)只讀的常量。
es6學(xué)習(xí)筆記-let,const和塊級(jí)作用域_v1.0 塊級(jí)作用域
javascript 原來是沒有塊級(jí)作用域的,只有全局作用域和函數(shù)作用域
例子1因?yàn)闆]有塊級(jí)作用域,所以每次的i都是一樣
var a = []; for (var i = 0; i < 10; i++) {//變量i是var聲明的,在全局范圍內(nèi)都有效 a[i] = function () { console.log(i); //每次的i變化都是全局的,所以每一個(gè)i的值都會(huì)變成最終的10 }; } a[1](); //返回10 a[6](); //返回10例子2
這里可以跟以前在
function createFunctions() { var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function () { //這是一個(gè)閉包 //因?yàn)殚]包保存的是整個(gè)createFunctions變量對(duì)象,所以當(dāng)他執(zhí)行完成的時(shí)候(for循環(huán)結(jié)束), //i是等于10的,所以就會(huì)是10,由始至終,閉包里面引用的都是一整個(gè)變量對(duì)象,而不是一個(gè)變量 return i; }; } return result; //返回的是一個(gè)數(shù)組,數(shù)組里面每一個(gè)項(xiàng)目都是一個(gè)function } var test = createFunctions(); for (var i = 0; i < 10; i++) { //需要執(zhí)行這個(gè) function 才能夠獲取里面的值 console.log(test[i]());//都是10 }
//看看區(qū)別,這里會(huì)傳入一個(gè)參數(shù)來避免使用變量對(duì)象的參數(shù) function createFunctions() { var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function (num) {//這是一個(gè)匿名函數(shù),參數(shù)是 num return function () {// 這是一個(gè)閉包,不過這個(gè)閉包訪問的num是我們傳入的num,即使閉包保存一整個(gè)變量對(duì)象,但是我們將變量對(duì)象改成了外面這個(gè)匿名函數(shù) return num; //相當(dāng)于在閉包外面包了一層活動(dòng)對(duì)象,將活動(dòng)對(duì)象改變成能夠改變值 num的活動(dòng)對(duì)象 }; }(i);//這個(gè)匿名函數(shù)會(huì)立即執(zhí)行,并且傳入了 i 作為 num } return result; //返回的是一個(gè)數(shù)組,數(shù)組里面每一個(gè)項(xiàng)目都是一個(gè)function } var test = createFunctions(); for (var i = 0; i < 10; i++) { //需要執(zhí)行這個(gè) function 才能夠獲取里面的值 console.log(test[i]());//返回0-9 }
例子3雖然這里是說閉包保存的是整個(gè)變量對(duì)象,導(dǎo)致了i的值跟著變量對(duì)象一起變化,不過也是殊途同歸,這里只是替換為做全局對(duì)象來做例子
這里還原到真實(shí)的應(yīng)用
//這里運(yùn)行報(bào)錯(cuò):Uncaught TypeError: Cannot read property "innerText" of undefined at HTMLButtonElement.( var buttons = document.querySelectorAll(".button"); var output = document.querySelector("#output"); for(var i =0;i 總的來說,那么在以前的js里面要實(shí)現(xiàn)塊級(jí)作用域的話:
要么使用函數(shù)作用域,例如在函數(shù)里面重新定義變量
要么就使用類似閉包的方式,使用獨(dú)立的變量
letlet的作用就是將變量保持在塊級(jí)作用域里面,那就沒有了跟其他作用域互搶的情況了.
var會(huì)出現(xiàn)變量提升的情況(變量可以在聲明前使用),但是let沒有
不允許重復(fù)聲明(var可以,let不可以)
改成用let之后
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[1](); // 返回1 a[6](); // 返回6其他例子也是可以簡(jiǎn)單的改成let代替var就可以生效了.
塊級(jí)作用域與函數(shù)聲明es5規(guī)定函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能再塊級(jí)作用域聲明(一般模式可以使用,但是嚴(yán)格模式不可以使用)
es6規(guī)定,明確允許在塊級(jí)作用域之中聲明函數(shù)
但是考慮到舊代碼的問題,為了減輕因此產(chǎn)生的不兼容問題,ES6在附錄B里面規(guī)定,瀏覽器的實(shí)現(xiàn)可以不遵守上面的規(guī)定,有自己的行為方式。
考慮到環(huán)境導(dǎo)致的行為差異太大,應(yīng)該避免在塊級(jí)作用域內(nèi)聲明函數(shù)。如果確實(shí)需要,也應(yīng)該寫成函數(shù)表達(dá)式,而不是函數(shù)聲明語句。
// 函數(shù)聲明語句 { let a = "secret"; function f() { return a; } } // 函數(shù)表達(dá)式 { let a = "secret"; let f = function () { return a; }; }for循環(huán)for循環(huán)還有一個(gè)特別之處,就是循環(huán)語句部分是一個(gè)父作用域,而循環(huán)體內(nèi)部是一個(gè)多帶帶的子作用域。
for (let i = 0; i < 3; i++) { //i在for循環(huán)變化 let i = "abc"; //然后for循環(huán)內(nèi)部的i也設(shè)置了一個(gè) console.log(i); } // abc // abc // abc上面代碼輸出了3次abc,這表明函數(shù)內(nèi)部的變量i和外部的變量i是分離的。
constconst聲明一個(gè)只讀的常量。一旦聲明,常量的值就不能改變。
const實(shí)際上保證的,并不是變量的值不得改動(dòng),而是變量指向的那個(gè)內(nèi)存地址不得改動(dòng)。
對(duì)于簡(jiǎn)單類型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的那個(gè)內(nèi)存地址,因此等同于常量。
于復(fù)合類型的數(shù)據(jù)(主要是對(duì)象和數(shù)組),變量指向的內(nèi)存地址,保存的只是一個(gè)指針,const只能保證這個(gè)指針是固定的,至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的,就完全不能控制了
const foo = {}; // 為 foo 添加一個(gè)屬性,可以成功,雖然設(shè)置了常量,但是里面的屬性還是能夠改變 foo.prop = 123; foo.prop // 123 // 將 foo 指向另一個(gè)對(duì)象,就會(huì)報(bào)錯(cuò),這里看到常量還是設(shè)置成功的 foo = {}; // TypeError: "foo" is read-only如果需要將對(duì)象凍結(jié),保證為一個(gè)真正的"常量",需要用Object.freeze,而且為了保證排除對(duì)象里面包含對(duì)象的情況,需要遞歸凍結(jié)
//普通凍結(jié) const foo = Object.freeze({}); // 常規(guī)模式時(shí),下面一行不起作用; // 嚴(yán)格模式時(shí),該行會(huì)報(bào)錯(cuò) foo.prop = 123; //遞歸凍結(jié) var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, value) => { if ( typeof obj[key] === "object" ) { constantize( obj[key] ); } }); };總而言之:一般情況下,使用const來定義值的存儲(chǔ)容器(變量)
只有在值容器明確地被確定將會(huì)被改變時(shí)才使用let來定義變量
不在使用var
參考引用:
es6-函數(shù)的擴(kuò)展
es實(shí)戰(zhàn)2015
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/81940.html
摘要:學(xué)習(xí)筆記函數(shù)擴(kuò)展函數(shù)參數(shù)的默認(rèn)值如果參數(shù)默認(rèn)值是變量,那么參數(shù)就不是傳值的,而是每次都重新計(jì)算默認(rèn)值表達(dá)式的值。屬性函數(shù)的屬性,返回該函數(shù)的函數(shù)名。箭頭函數(shù)詳細(xì)鏈接參考引用函數(shù)擴(kuò)展 es6學(xué)習(xí)筆記-函數(shù)擴(kuò)展_v1.0 函數(shù)參數(shù)的默認(rèn)值 function Point(x = 0, y = 0) { this.x = x; this.y = y; } var p = ne...
摘要:因?yàn)榧^函數(shù)本身沒有所以不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用命令,否則會(huì)拋出一個(gè)錯(cuò)誤。箭頭函數(shù)不可以使用對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在。 es6學(xué)習(xí)筆記-箭頭函數(shù)_v1.0 箭頭函數(shù)使用方法 var f = v => v; //普通函數(shù)配合箭頭函數(shù)寫法,這里并且是傳參的 //相當(dāng)于 var f = function(v) { return v; }; /*-----------...
摘要:學(xué)習(xí)筆記頂層對(duì)象雖然是筆記但是基本是抄了一次大師的文章了頂層對(duì)象頂層對(duì)象,在瀏覽器環(huán)境指的是對(duì)象,在指的是對(duì)象。之中,頂層對(duì)象的屬性與全局變量是等價(jià)的。的寫法模塊的寫法上面代碼將頂層對(duì)象放入變量。參考引用頂層對(duì)象實(shí)戰(zhàn) es6學(xué)習(xí)筆記-頂層對(duì)象_v1.0 (雖然是筆記,但是基本是抄了一次ruan大師的文章了) 頂層對(duì)象 頂層對(duì)象,在瀏覽器環(huán)境指的是window對(duì)象,在Node指的是gl...
摘要:學(xué)習(xí)筆記字符串的擴(kuò)展字符的表示法允許使用的形式表示一個(gè)字符,但在之前,單個(gè)碼點(diǎn)僅支持到,超出該范圍的必須用雙字節(jié)形式表示,否則會(huì)解析錯(cuò)誤。返回布爾值,表示參數(shù)字符串是否在源字符串的頭部。,是引入了字符串補(bǔ)全長度的功能。 es6學(xué)習(xí)筆記-字符串的擴(kuò)展_v1.0 字符的Unicode表示法 JavaScript 允許使用uxxxx的形式表示一個(gè)字符,但在 ES6 之前,單個(gè)碼點(diǎn)僅支持u00...
摘要:學(xué)習(xí)模塊不是對(duì)象,而是通過命令顯式指定輸出的代碼,輸入時(shí)也采用靜態(tài)命令的形式。的模塊自動(dòng)采用嚴(yán)格模式命令用于規(guī)定模塊的對(duì)外接口,命令用于輸入其他模塊提供的功能。該文件內(nèi)部的所有變量,外部無法獲取。 es6 學(xué)習(xí)-module_v1.0 ES6模塊不是對(duì)象,而是通過export命令顯式指定輸出的代碼,輸入時(shí)也采用靜態(tài)命令的形式。 ES6的模塊自動(dòng)采用嚴(yán)格模式 export命令用于規(guī)定模...
閱讀 1745·2021-11-24 10:18
閱讀 2255·2021-11-18 13:20
閱讀 2347·2021-08-23 09:46
閱讀 1007·2019-08-30 15:56
閱讀 2851·2019-08-30 15:53
閱讀 750·2019-08-30 14:22
閱讀 478·2019-08-29 15:34
閱讀 2548·2019-08-29 12:14