本節(jié)將會重點分析ES6引入的第6種基本類型:Symbol(符號)。符號可以像字符串那樣作為對象的屬性名,只是它有唯一性的特點,可以避免屬性名之間的沖突。

          一、創(chuàng)建


            符號沒有字面量形式,只能通過Symbol()函數(shù)創(chuàng)建。該函數(shù)有一個可選的參數(shù),只是用來描述當(dāng)前符號,除了便于閱讀之外,沒有其他用途。由此可知,即使兩個符號的描述相同,它們還是不能畫等號。注意,Symbol()不是構(gòu)造函數(shù),因此不能和new運算符組合使用,否則會拋出類型錯誤。下面用一個例子展示符號的創(chuàng)建。
          var sym1 = Symbol(), sym2 = Symbol("name"), sym3 = Symbol("name"), sym4 = new
          Symbol();//拋出類型錯誤 console.log(sym2 === sym3); //false
            如果要識別一個變量是否為符號,可以用typeof運算符。ES6擴(kuò)展了它,當(dāng)檢測到符號時,能返回一個新的類型字符串“symbol”,具體如下所示。
          typeof sym1; //"symbol" typeof sym2; //"symbol"
          二、類型轉(zhuǎn)換

            符號在類型轉(zhuǎn)換時表現(xiàn)得并不靈活,它無法與數(shù)字或字符串進(jìn)行運算,也無法顯式的轉(zhuǎn)換成數(shù)字。如下所示,后面四條語句在執(zhí)行時都會報錯。
          var sym = Symbol("age"); Number(sym); parseInt(sym); 1 + sym; "" + sym;
            不過,符號可以顯式的轉(zhuǎn)換成字符串或布爾值,具體如下所示。
          Boolean(sym);   //true !sym;   //false sym.toString(); //"Symbol(age)"
          String(sym);//"Symbol(age)"
          三、全局共享


            ES6會在內(nèi)部維護(hù)一張全局符號注冊表,通過Symbol.for()方法,可以登記指定符號,使其變成一個全局有效地符號,從而達(dá)到全局共享。該方法只接收一個參數(shù),這個參數(shù)既是注冊表中的鍵值,同時也是此符號的描述。下面的代碼調(diào)用了兩次Symbol.for()方法,傳遞了相同的參數(shù),返回的卻是同一個全局符號。
          var sym1 = Symbol.for("name"), sym2 = Symbol.for("name"); console.log(sym1 ===
          sym2);//true

            在上面的代碼中,第一次調(diào)用Symbol.for()方法時,會在注冊表中搜索鍵值為“name”的符號,由于沒有找到,所以就會創(chuàng)建一個新的符號。而在第二次調(diào)用Symbol.for()方法時,由于傳遞的鍵值與前一次相同,因此會返回剛剛的那個符號。從而可知,對變量sym1和sym2進(jìn)行全等比較,返回的結(jié)果將是true。

            如果要獲取某個全局符號所對應(yīng)的鍵值(即它的描述),那么可以通過Symbol.keyFor()實現(xiàn),具體操作如下所示。
          Symbol.keyFor(sym1); //"name" Symbol.keyFor(sym2); //"name"
          四、屬性名


            本節(jié)開頭曾提到過對象的屬性名可以用符號表示,而這類屬性可以有三種賦值方式。第一種是用方括號,注意,不能用點號,因為點號后面的標(biāo)識符會被識別成字符串而不是符號。下面代碼分別用方括號和點號為obj對象的sym屬性賦值,前者被識別成了符號屬性,而后者卻被識別成了字符串屬性。
          var sym = Symbol("name"), obj = {}; obj[sym] = "strick"; obj.sym = "strick";
          console.log(obj);//{Symbol(name): "strick", sym: "strick"}
            第二種是在創(chuàng)建對象字面量時,用計算屬性名的方式(即屬性名被方括號包裹)為其賦值,如下所示。
          obj = { [sym]: "freedom" };
            第三種是調(diào)用Object.defineProperty()或Object.defineProperties()方法來為符號屬性賦值,如下所示。
          Object.defineProperty(obj, sym, { value: "justice" });

            注意,符號屬性是不可枚舉的,既不能被for-in等循環(huán)遍歷到,也不能被Object.keys()、Object.getOwnPropertyNames()等方法讀取到。但可以通過Object.getOwnPropertySymbols()方法獲得對象的符號屬性,具體如下所示。
          obj = { [sym]: "freedom", age: 28 }; Object.keys(obj);    //["age"]
          Object.getOwnPropertyNames(obj);//["age"] Object.getOwnPropertySymbols(obj); //
          [Symbol(name)]
          五、內(nèi)置符號

            ES6提供了一些內(nèi)置符號,也叫做知名符號(Well-Known
          Symbol)。它們暴露了語言的內(nèi)部邏輯,允許開發(fā)人員修改或拓展規(guī)范所描述的對象特征或行為。每一個內(nèi)置符號對應(yīng)Symbol對象的一個屬性,例如Symbol.hasInstance、Symbol.iterator等,表1列出了11個內(nèi)置符號。

          表1? 內(nèi)置符號

          屬性名稱 值類型 描述
          hasInstance 方法 當(dāng)使用instanceof運算符時會調(diào)用該方法
          isConcatSpreadable 布爾值 當(dāng)對象作為Array.prototype.concat()方法的參數(shù)時,控制該對象是否被展開
          iterator 方法 返回一個迭代器,用于定義一個可迭代的對象
          match 方法 當(dāng)對象作為String.prototype.match()方法的參數(shù)時,該方法會被調(diào)用
          replace 方法 當(dāng)對象作為String.prototype.replace()方法的參數(shù)時,該方法會被調(diào)用
          search 方法 當(dāng)對象作為String.prototype.search()方法的參數(shù)時,該方法會被調(diào)用
          split 方法 當(dāng)對象作為String.prototype.split()方法的參數(shù)時,該方法會被調(diào)用
          species 方法 創(chuàng)建派生類的構(gòu)造函數(shù)
          toPrimitive 方法 當(dāng)對象需要轉(zhuǎn)換成原始值(即執(zhí)行ToPrimitive抽象操作)時,該方法會被調(diào)用
          toStringTag 字符串 指定對象的類型,可在調(diào)用Object.prototype.toString()方法的時候返回
          unscopables 對象 保存在這個對象中的屬性將不能被with語句所引用
            下面會給出4個內(nèi)置符號的示例,分別是hasInstance、isConcatSpreadable、match和toStringTag。
          let digit = { [Symbol.hasInstance](number) { return !(number % 2); //判斷數(shù)字是否為偶數(shù)
          } };1 instanceof digit; //false 2 instanceof digit; //true let arr1 = [3, 4];
          [1, 2].concat(arr1); //[1, 2, 3, 4] let arr2 = [3, 4];
          arr2[Symbol.isConcatSpreadable]= false; //禁止展開 [1, 2].concat(arr2); //[1, 2,
          [3, 4]] let regex = { [Symbol.match](str) { return str.substr(0, 10); } },
          message= "My name is strick"; message.match(regex);   //"My name is" let people
          = { [Symbol.toStringTag]: "People" }; people.toString(); //"[object People]"
          ?

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                黑人导航| 精品久久久久久中文字幕18 | 91桃色污 | 三级片毛片在线观看 | 国产盗摄xxxx视频xxxx |