ES6 Symbol

概覽

const mySymbol = Symbol('mySymbol');
console.log(mySymbol); // Symbol(mySymbol)
console.log(mySymbol === Symbol('mySymbol')); // false
console.log(typeof mySymbol); // 'symbol'

基本數據類型Symbol

ES6 六種基本數據類型: StringNumberBooleanNullUndefinedSymbol
ES6 七種數據類型: StringNumberBooleanNullUndefinedObjectSymbol

類型轉換

  • 轉字符串(不支持強制轉換成字符串)javascript

    // 轉String
    console.log(mySymbol.toString()); // 'Symbol(mySymbol)'
    console.log(String(mySymbol)); // 'Symbol(mySymbol)'
    // console.log(mySymbol + ''); // Cannot convert a Symbol value to a string
    // console.log(`${mySymbol}`); // Cannot convert a Symbol value to a string
  • 轉Booleanjava

    // 轉Boolean  
    console.log(Boolean(mySymbol)); // true
    console.log(!mySymbol); // false
    if(mySymbol){
      console.log(123); // 123
    }
  • 轉Number(不支持)git

    // console.log(Number(mySymbol)); //Uncaught TypeError: Cannot convert a Symbol value to a number
    // console.log(+mySymbol); //Uncaught TypeError: Cannot convert a Symbol value to a number
    // console.log(1+mySymbol); //Uncaught TypeError: Cannot convert a Symbol value to a number

自定義Symbol屬性鍵

  • 第一種方法github

    let ourSymbol = Symbol();
    let a = {};
    a[ourSymbol] = 'hello'; 
    console.log(a); // {Symbol(): "hello"}
  • 第二種方法正則表達式

    let ourSymbol = Symbol();
    let b = {
      [ourSymbol]: 'world'
    };
    console.log(b); // {Symbol(): "world"}
  • 第三種方法數組

    let ourSymbol = Symbol();
    let c = {};
    Object.defineProperty(c,ourSymbol,{value: '!'});
    console.log(c); // {Symbol(): "!"}

注意:不支持點運算符異步

let ourSymbol = Symbol();
a.ourSymbol = '點運算符';
console.log(a[ourSymbol]); // undefined
console.log(a['ourSymbol']); // '點運算符'

注意:在對象內部,使用Symbol值定義屬性時,Symbol值必須放在方括號中。async

let s = Symbol();
let objNew = {
  [s]:function(arg){
    console.log(arg);
  }
};
let objNew1 = {
  [s](arg){
    console.log(arg);
  }
};
objNew[s](123)
objNew1[s](234)

Symbol做爲屬性鍵

const MY_KEY = Symbol();
const MY = Symbol();
const FOO = Symbol();
const objkEY = {
  [MY]:333,
  [FOO](fo){
    return fo
  }
};
objkEY[MY_KEY] = 123;
console.log(objkEY[MY_KEY]); // 123
console.log(objkEY[MY]); // 333
console.log(objkEY[FOO](11)); // 11

枚舉屬性鍵

const keyObj = {
  [Symbol('my_key')]: 1,
  enum: 2,
  nonEnum: 3
}
Object.defineProperty(keyObj, 'nonEnum', {enumerable: false});
console.log(keyObj); // {enum: 2, nonEnum: 3, Symbol(my_key): 1}
console.log(Object.getOwnPropertyNames(keyObj)); // 忽略Symbol屬性鍵:["enum", "nonEnum"]
console.log(Object.getOwnPropertySymbols(keyObj)); // 忽略字符串屬性鍵:[Symbol(my_key)]
console.log(Reflect.ownKeys(keyObj)); // 遍歷全部屬性鍵:["enum", "nonEnum", Symbol(my_key)]
console.log(Object.keys(keyObj)); // 遍歷可枚舉字符串屬性鍵:["enum"]

Symbol用來表示概念

用於定義一種常量,保證這組常量不相等函數

let levels = {
  DEBUG:Symbol('debug'),
  INFO:Symbol('info'),
  WARN:Symbol('warn')
}
console.log(levels.DEBUG, 'debug message');
console.log(levels.INFO, 'info message');

其餘任何值都不能有相同的值————保證switch語句設計的方式工做ui

const COLOR_RED = Symbol();
const COLOR_GREEN = Symbol();
function getComplement(color) {
  switch(color) {
    case COLOR_RED:
      return COLOR_GREEN;
    case COLOR_GREEN:
      return COLOR_RED;
    default: 
      throw new Error('undefined')
  }
}
console.log(getComplement(COLOR_RED));
console.log(getComplement(COLOR_GREEN));
// console.log(getComplement('21321'));

Symbol的方法和屬性

console.dir(Symbol);
// ƒ Symbol()
// arguments: (...)
// asyncIterator: Symbol(Symbol.asyncIterator)
// caller: (...)
// for: ƒ for()
// hasInstance: Symbol(Symbol.hasInstance)
// isConcatSpreadable: Symbol(Symbol.isConcatSpreadable)
// iterator: Symbol(Symbol.iterator)
// keyFor: ƒ keyFor()
// length: 0
// match: Symbol(Symbol.match)
// matchAll: Symbol(Symbol.matchAll)
// name: "Symbol"
// prototype: Symbol {constructor: ƒ Symbol()
//     description: (...)
//     toString: ƒ toString()
//     valueOf: ƒ valueOf()
//     Symbol(Symbol.toPrimitive): ƒ [Symbol.toPrimitive]()
//     Symbol(Symbol.toStringTag): "Symbol"
//     get description: ƒ description()
//     __proto__: Object
// }
// replace: Symbol(Symbol.replace)
// search: Symbol(Symbol.search)
// species: Symbol(Symbol.species)
// split: Symbol(Symbol.split)
// toPrimitive: Symbol(Symbol.toPrimitive)
// toStringTag: Symbol(Symbol.toStringTag)
// unscopables: Symbol(Symbol.unscopables)
Symbol.for() 接受一個字符串做參數,而後搜索有沒有以該參數做爲名稱的Symbol值。若是有就返回Symbol值,不然返回一個以該字符串爲名稱的Symbol值
Symbol.keyFor() 返回一個已登記的 Symbol類型值的key
const s1 = Symbol.for('foo');
const s2 = Symbol.for('foo');
const s3 = Symbol('foo');
const s4 = Symbol('foo');
console.log(s1 === s2); // true
console.log(s3 === s4); // false
console.log(Symbol.keyFor(s1)); // 'foo'
console.log(Symbol.keyFor(s2)); // 'foo'
console.log(Symbol.keyFor(s3)); // undefined
console.log(Symbol.keyFor(s4)); // undefined
Symbol.prototype.toString() 方法返回當前 symbol 對象的字符串表示。
Symbol.prototype.valueOf() 方法返回當前 symbol 對象所包含的 symbol 原始值。
// console.log(Symbol('foo') + 'bar'); // Uncaught TypeError: Cannot convert a Symbol value to a string
console.log(Symbol('foo').toString() + 'bar'); // Symbol(foo)bar
console.log(Object(Symbol('foo')).toString() + 'bar'); // Symbol(foo)bar
Symbol("desc").toString();   // "Symbol(desc)"
// well-known symbols
Symbol.iterator.toString();  // "Symbol(Symbol.iterator)
// global symbols
Symbol.for("foo").toString() // "Symbol(foo)"

// Object(Symbol("foo")) + "bar";
// TypeError: can't convert symbol object to primitive
// 沒法隱式的調用 valueOf() 方法
console.log(Object(Symbol("foo")).valueOf()); // Symbol(foo)
console.log(Symbol("foo").valueOf()); // Symbol(foo)
// console.log(Object(Symbol("foo")).valueOf() + "bar");
// TypeError:  can't convert symbol to string
// 手動調用 valueOf() 方法,雖然轉換成了原始值,但 symbol 原始值不能轉換爲字符串
console.log(Object(Symbol("foo")).toString() + "bar");
// "Symbol(foo)bar",須要手動調用 toString() 方法才行

Symbol.asyncIterator 符號指定了一個對象的默認異步迭代器。若是一個對象設置了這個屬性,它就是異步可迭代對象,可用於for await...of循環。

Symbol.hasInstance用於判斷某對象是否爲某構造器的實例。所以你能夠用它自定義instanceof操做符在某個類上的行爲。

Symbol.isConcatSpreadable符號等於一個布爾值;用於配置某對象做爲Array.prototype.concat()方法的參數時是否展開其數組元素。

Symbol.iterator爲每個對象定義了默認的迭代器。該迭代器能夠被for...of循環使用。

Symbol.match指定了匹配的是正則表達式而不是字符串。

Symbol.matchAll返回一個迭代器,該迭代器根據字符串生成正則表達式的匹配項。

Symbol.replace這個屬性指定了當一個字符串替換所匹配字符串時所調用的方法。

Symbol.search 指定了一個搜索方法,這個方法接受用戶輸入的正則表達式,返回該正則表達式在字符串中匹配到的下標。

Symbol.species是個函數值屬性,其被構造函數用以建立派生對象。

Symbol.split指向 一個正則表達式的索引處分割字符串的方法。

Symbol.toPrimitive 是一個內置的 Symbol 值,它是做爲對象的函數值屬性存在的,當一個對象轉換爲對應的原始值時,會調用此函數。

Symbol.toStringTag 是一個內置 symbol,它一般做爲對象的屬性鍵使用,對應的屬性值應該爲字符串類型,這個字符串用來表示該對象的自定義類型標籤,一般只有內置的 Object.prototype.toString() 方法會去讀取這個標籤並把它包含在本身的返回值裏。

Symbol.unscopables 指用於指定對象值,其對象自身和繼承的從關聯對象的 with 環境綁定中排除的屬性名稱。

ES6 Symbol

相關文章
相關標籤/搜索