成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ECMAScript6(10):Symbol基本類型

lavor / 1063人閱讀

摘要:基本類型是一種解決命名沖突的工具。這樣,就有了個(gè)基本類型和個(gè)復(fù)雜類型使用需要注意以下幾點(diǎn)和一樣不具有構(gòu)造函數(shù),不能用調(diào)用。判斷對(duì)象是否某個(gè)構(gòu)造函數(shù)的實(shí)例,運(yùn)算符會(huì)調(diào)用它是一個(gè)數(shù)組對(duì)象屬性。即,當(dāng)存在時(shí),以此為構(gòu)造函數(shù)構(gòu)建對(duì)象。

Symbol基本類型

Symbol 是一種解決命名沖突的工具。試想我們以前定義一個(gè)對(duì)象方法的時(shí)候總是要檢查是否已存在同名變量:

if(String && String.prototype && String.prototype.getCodeWith){
  String.prototype.getCodeWith = function(){};
}

可是這樣寫,即便已存在同名方法,但他們實(shí)現(xiàn)的功能不一定一樣,而且函數(shù)的接口也不一定適合自己。這樣我們就不得不再給自己的函數(shù)起個(gè)其他的名字,可以萬(wàn)一又存在呢?

于是引入了 Symol,用來(lái)產(chǎn)生一個(gè)全局唯一的標(biāo)識(shí)符,你可以放心的使用它。
它接受一個(gè)字符串參數(shù),作為該標(biāo)識(shí)符的描述:

var sym = Symbol("Discription");
var temp = Symbol("Discription");
console.log(sym);             //Symbol(Discription)
console.log(sym.valueOf());   //Symbol(Discription)
console.log(sym.toString());  //"Symbol(Discription)"
console.log(sym == temp);     //false

描述符是用來(lái)幫助開(kāi)發(fā)人員區(qū)別不同是 symbol,不具備其他意義, 所以 symbol 值只有toString()valueOf() 方法。
Symbol 作為一個(gè)基本類型存在于 js 中。這樣,js 就有了6個(gè)基本類型: null, undefined, Boolean, Number, String, Symbol 和1個(gè)復(fù)雜類型: Object
使用 Symbol 需要注意以下幾點(diǎn):

Symbol 和 null, undefined 一樣不具有構(gòu)造函數(shù),不能用 new 調(diào)用。

Symbol 值不能轉(zhuǎn)為數(shù)字,所以不能參與任何算術(shù),邏輯運(yùn)算

Symbol 雖然有 toString() 但 toString 得到的不是字符串,所以不能用于字符串鏈接,不能用于模板字符串

Symbol 可以轉(zhuǎn)換為 Boolean, 用在條件語(yǔ)句中,但所有 Symbol 都是邏輯 true

Symbol 作為屬性名時(shí),該屬性是公開(kāi)的,不是私有的

Symbol用作屬性名

這個(gè)應(yīng)該不陌生了,和普通標(biāo)識(shí)符用法類似,只是不能使用.訪問(wèn)和定義,必須使用[]

var sym = Symbol("abc");
var fun = Symbol("getSym");

var a = {};
a[sym] = 1;

var b = {
  [sym]: 1,
  [fun](){
    console.log(this[sym]);
  }
};

var c = Object.defineProperty({}, sym, {value: 1});

a[sym];   //1
b[sym];   //1
c[sym];   //1
b[fun]();  //1

當(dāng)然也可以定義一些常量,就像英語(yǔ)中 Symbol 代表一種象征,一個(gè)符號(hào):

var log = {
  DEBUG: Symbol("debug"),
  ERROR: Symbol("error"),
  WARNING: Symbol("warning"),
}

需要注意,Symbol 屬性只有Object.getOwnPropertySymbols(obj)Reflect.ownKey(obj) 可以遍歷到:

Object.getOwnPropertySymbols(obj): 返回自身所有 Symbol 屬性名的數(shù)組,包括不可枚舉屬性

Reflect.ownKey(obj): 返回自身所有屬性名數(shù)組,包括不可枚舉屬性和 Symbol 屬性名

var sym = Symbol("pro");
var o = {
  a: 1,
  b: 2,
  [sym]: 3
}
Object.getOwnPropertySymbols(o);     //[Symbol(pro)]
Reflect.ownKeys(o);                  //["a", "b", Symbol(pro)]

我們可以利用這個(gè)方法,構(gòu)造一些非私有的內(nèi)部變量:

var size = Symbol("size");
class Collection{
  constructor(){
    this[size] = 0;
  }
  add(num){
    this[this[size]] = item;
    this[size]++;
  }
  static sizeOf(instance){
    return instance[size];
  }
}
var x = new Collection();
console.log(Collection.sizeOf(x));     //0
x.add("foo");
console.log(Collection.sizeOf(x));     //1

console.log(Object.keys(x));     //["0"]
console.log(Object.getOwnPropertyNames(x));   //["0"]
console.log(Object.getOwnPropertySymbols(x));   //[Symbol(size)]
Symbol的靜態(tài)方法

Symbol.for("string"): 登記并重用一個(gè) symbol 值

Symbol.for("aa") === Symbol.for("aa");    //true
Symbol("aa") === Symbol("aa");            //false

Symbol.keyFor(symbol): 返回一個(gè)已登記的 Symbol 描述, 未登記的 Symbol 返回 undefined

var s1 = Symbol.for("aa");
var s2 = Symbol("aa");
Symbol.keyFor(s1);    //"aa"
Symbol.keyFor(s2);    //undefined

注意 Symbol 的登記是全局的:

iframe = document.createElement("iframe");
iframe.src = String(window.location);
document.body.appendChild(iframe);
iframe.contentWindow.Symbol.for("aa") === Symbol.for("aa");    //true
內(nèi)置的 Symbol 值

ES6 提供了12個(gè)內(nèi)置的 Symbol 值,這12個(gè)值,都是對(duì)象的,且都不可枚舉、不可配置、不可修改。因?yàn)樗鼈兙哂衅涮厥庖饬x:

Symbol.hasInstance: 指向一個(gè)內(nèi)部方法。判斷對(duì)象是否某個(gè)構(gòu)造函數(shù)的實(shí)例,instanceof 運(yùn)算符會(huì)調(diào)用它

Symbol.isConcatSpreadable: 是一個(gè)數(shù)組對(duì)象屬性。如果為 false 該屬性在 concat 過(guò)程不會(huì)被展開(kāi)。數(shù)組對(duì)象該屬性默認(rèn)值為 true, 類數(shù)組對(duì)象該屬性默認(rèn)值為 false

var arr = [3,4];
[1,2].concat(arr);   //[1,2,3,4]
arr[Symbol.isConcatSpreadable] = false;
[1,2].concat(arr);   //[1,2,[3,4]]

對(duì)于一個(gè)類而言,該屬性必須返回 boolean 類型

class A1 extends Array{
  [Symbol.isConcatSpreadable](){
    return true;
  }
}
class A2 extends Array{
  [Symbol.isConcatSpreadable](){
    return false;
  }
}
let a1 = new A1();
a1[0] = 3;
a1[1] = 4;
let a2 = new A2();
a2[0] = 5;
a2[1] = 6;
[1,2].concat(a1).concat(a2);  //[1, 2, 3, 4, 5, 6]

Symbol.species: 指向一個(gè)方法。將對(duì)象作為構(gòu)造函數(shù)調(diào)用時(shí),系統(tǒng)內(nèi)部會(huì)調(diào)用這個(gè)方法。即,當(dāng) this.constructor[Symbol.species]存在時(shí),以此為構(gòu)造函數(shù)構(gòu)建對(duì)象。

Symbol.match: 指向一個(gè)函數(shù)。當(dāng)執(zhí)行 str.match(obj) 的時(shí)候, 如果 obj 存在該屬性,調(diào)用該方法并返回該方法的返回值

String.prototype.match(searchValue);
//相當(dāng)于
SearchValue[Symbol.match](this);
//實(shí)例
class myMatch{
  constructor(str){
    this.content = str;
  }
  [Symbol.match](str){
    return this.content.indexOf(str);
  }
}
"e".match(new myMatch("Hello"));    //1

Symbol.replace: 指向一個(gè)函數(shù)。和上一個(gè)方法類似的,當(dāng)執(zhí)行 str.replace(obj,replaceValue) 的時(shí)候, 如果 obj 存在該屬性,調(diào)用該方法并返回該方法的返回值

String.prototype.replace(searchValue, replaceValue);
//相當(dāng)于
SearchValue[Symbol.replace](this, replaceValue);

Symbol.search: 指向一個(gè)函數(shù)。和上一個(gè)方法類似的,當(dāng)執(zhí)行 str.search(obj) 的時(shí)候, 如果 obj 存在該屬性,調(diào)用該方法并返回該方法的返回值

String.prototype.search(searchValue);
//相當(dāng)于
SearchValue[Symbol.search](this);

Symbol.split: 指向一個(gè)函數(shù)。和上一個(gè)方法類似的,當(dāng)執(zhí)行 str.split(obj,limit) 的時(shí)候, 如果 obj 存在該屬性,調(diào)用該方法并返回該方法的返回值

String.prototype.split(seperator,limit);
//相當(dāng)于
seperator[Symbol.split](this,limit);

Symbol.iterator: 指向默認(rèn)的遍歷器方法。對(duì)象在 for...of 中默認(rèn)調(diào)用該方法。

class Collector{
  constructor(...vals){
    this.nums = vals;
  }
  *[Symbol.iterator](){
    let i = this.nums.length;
    while(i){
      i--;
      yield this.nums[i];
    }
  }
}
var collector = new Collector(1,2,3,4,5);
for(let value of collector){
  console.log(value);        //依次輸出 5 4 3 2 1
}

Symbol.toPrimitive: 指向一個(gè)方法。對(duì)象被轉(zhuǎn)為原始類型值時(shí)會(huì)調(diào)用該方法。該方法介紹一個(gè)字符串參數(shù),可選參數(shù):

"number": 此時(shí)轉(zhuǎn)換成數(shù)值,應(yīng)返回?cái)?shù)值類型

"string": 此時(shí)轉(zhuǎn)換成字符串,應(yīng)返回字符串類型

"default": 此時(shí)轉(zhuǎn)換成數(shù)值或字符串,應(yīng)返回?cái)?shù)值或字符串類型

var obj = {
  [Symbol.toPrimitive](hint){
    switch(hint){
      case "number": return 1234;
      case "string": return "hello";
      case "default": return "default";
      default: throw new Error();
    }
  }
};
console.log(obj.toString());     //[object Object]
console.log(obj.valueOf());      //{
console.log(2 * obj);            //2468
console.log(2 + obj);            //2default
console.log(obj === "hello");    //false
console.log(String(obj));        //hello

Symbol.unscopables: 該讀取器指向一個(gè)對(duì)象。指定了在使用 with語(yǔ)句 時(shí),那些屬性被 with 環(huán)境排除(無(wú)法訪問(wèn))

//例1
console.log(Array.prototype[Symbol.unscopables]);    //輸出如下,數(shù)組對(duì)象在 with 中不能訪問(wèn)這些屬性方法
//{
//copyWithin: true,
//entries: true,
//fill: true,
//find: true,
//findIndex: true,
//includes: true,
//keys: true
//}
//例2
//沒(méi)有 unscopables 時(shí)
class MyClass{
  foo(){return 1}
}
var foo = () => 2;
with(MyClass.prototype){
  foo();    //1
}

//有 unscopable 時(shí)
var foo = () => 2;
class MyClass{
  foo(){return 1;}
  get [Symbol.unscopables](){
    return {foo:true};
  }
}
with(MyClass.prototype){
  foo();    //2
}

Symbol.toStringTag: 指向一個(gè)方法。該方法指向函數(shù)名是對(duì)象 toString 返回值 [object Array]Array 部分。

var b = {
  [Symbol.toStringTag]:"Hello"
};
console.log(b.toString());    //"[object Hello]"

ES6 新增的 Symbol.toStringTag 如下:

JSON["Symbol.toStringTag"]: "JSON"

Math["Symbol.toStringTag"]: "Math"

Module對(duì)象 M["Symbol.toStringTag"]: "Module"

ArrayBuffer.prototype["Symbol.toStringTag"]: "ArrayBuffer"

DataView.prototype["Symbol.toStringTag"]: "DataView"

Map.prototype["Symbol.toStringTag"]: "Map"

Promise.prototype["Symbol.toStringTag"]: "Promise"

Set.prototype["Symbol.toStringTag"]: "Set"

%TypedArray%.prototype["Symbol.toStringTag"]: "Uint8Array"等9種

WeakMap.prototype["Symbol.toStringTag"]: "WeakMap"

WeakSet.prototype["Symbol.toStringTag"]: "WeakSet"

%MapIteratorPrototype%["Symbol.toStringTag"]: "Map Iterator"

%SetIteratorPrototype%["Symbol.toStringTag"]: "Set Iterator"

%StringIteratorPrototype%["Symbol.toStringTag"]: "String Iterator"

Symbol.prototype["Symbol.toStringTag"]: "Symbol"

Generator.prototype["Symbol.toStringTag"]: "Generator"

GeneratorFunction.prototype["Symbol.toStringTag"]: "GeneratorFunction"

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97447.html

相關(guān)文章

  • ECMAScript6標(biāo)準(zhǔn)入門(一)新增變量與數(shù)據(jù)結(jié)構(gòu)

    摘要:一簡(jiǎn)介與的關(guān)系是的規(guī)格,是的一種實(shí)現(xiàn)另外的方言還有和轉(zhuǎn)碼器命令行環(huán)境安裝直接運(yùn)行代碼命令將轉(zhuǎn)換成命令瀏覽器環(huán)境加入,代碼用環(huán)境安裝,,根目錄建立文件加載為的一個(gè)鉤子設(shè)置完文件后,在應(yīng)用入口加入若有使用,等全局對(duì)象及上方法安裝 一、ECMAScript6 簡(jiǎn)介 (1) 與JavaScript的關(guān)系 ES是JS的規(guī)格,JS是ES的一種實(shí)現(xiàn)(另外的ECMAScript方言還有Jscript和...

    Tangpj 評(píng)論0 收藏0
  • ECMAScript6學(xué)習(xí)筆記

    摘要:筆記和和是塊作用域的,是聲明常量用的。一個(gè)對(duì)象如果要有可被循環(huán)調(diào)用的接口,就必須在的屬性上部署遍歷器生成方法原型鏈上的對(duì)象具有該方法也可。這種方式會(huì)訪問(wèn)注冊(cè)表,其中存儲(chǔ)了已經(jīng)存在的一系列。這種方式與通過(guò)定義的獨(dú)立不同,注冊(cè)表中的是共享的。 ECMAScript6 筆記 let 和 const let和const是塊作用域的 ,const是聲明常量用的。 {let a = 10;} a ...

    CODING 評(píng)論0 收藏0
  • ECMAScript6(8):對(duì)象的擴(kuò)展

    基本擴(kuò)展 允許使用已有對(duì)象賦值定義對(duì)象字面量,并且只寫變量名即可 var name = Bob; var getName = function(){console.log(this.name);}; var person = {name, getName}; //相當(dāng)于 //var person = { //name: Bob, //getName: function(){console.log...

    pingan8787 評(píng)論0 收藏0
  • ECMAScript6 新特性——“對(duì)象的擴(kuò)展”

    摘要:屬性的簡(jiǎn)潔表示法允許直接寫入變量和函數(shù)作為對(duì)象的屬性和方法。,中有返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的不含繼承的所有可遍歷屬性的鍵名。對(duì)象的擴(kuò)展運(yùn)算符目前,有一個(gè)提案,將解構(gòu)賦值擴(kuò)展運(yùn)算符引入對(duì)象。 1 屬性的簡(jiǎn)潔表示法 ES6允許直接寫入變量和函數(shù)作為對(duì)象的屬性和方法。 寫入屬性 var name = value; var obj = { name }; console.log...

    Clect 評(píng)論0 收藏0
  • ECMAScript6(14):iterator 迭代器

    摘要:由于中引入了許多數(shù)據(jù)結(jié)構(gòu)算上原有的包括等等數(shù)組需要一個(gè)東西來(lái)管理他們這就是遍歷器。數(shù)組默認(rèn)遍歷器遍歷值相當(dāng)于依次輸出依次輸出依次輸出依次輸出不難看出默認(rèn)得到值而只能得到索引。即遍歷器的本質(zhì)就是一個(gè)指針。 由于 ES6 中引入了許多數(shù)據(jù)結(jié)構(gòu), 算上原有的包括Object, Array, TypedArray, DataView, buffer, Map, WeakMap, Set, We...

    toddmark 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<