Symbol

124 阅读1分钟

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

symbol作为对象属性是不能被forin/Object.keys()等方式遍历,只可以通过Object.getOwnPropertySymbols获取symbol

symbol消除魔术字符串(魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。)

let a = {
  name: 'xzm',
  age: 13,
  [Symbol('sex')]: 3,
}
console.log(a[Object.getOwnPropertySymbols(a)[0]])

const shapeType = {
  triangle: Symbol()
};
内置的 Symbol 值 共11种,参考es6 阮一峰
Symbol.hasInstance

arr instanceof Array 实际上调用的方法 Array[Symbol.hasInstance](arr)

Symbol.isConcatSpreadable

内置的Symbol.isConcatSpreadable符号用于配置某对象作为Array.prototype.concat()方法的参数时是否展开其数组元素。

let arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]

console.log(arr2[Symbol.isConcatSpreadable]);  //undefine
console.log(arr1.concat(arr2));                //[1, 2, 3, 4, 5, 6]

arr2[Symbol.isConcatSpreadable] = false
console.log(arr1.concat(arr2));                //[1, 2, 3, [4, 5, 6]]
Symbol.iterator

当对象拥有此属性的时候,才可以被迭代(Object是没有的)

//obj是个类数组,才可以使用array的iterator。常规的对象是不可以使用的
let obj = {
  0: 1,
  1: 2,
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
}

for (let item of obj) {
  console.log(item);
}
Symbol.toPrimitive 类型转换方面优先级最高
let a = {
  value: 0,
  // valueOf() {
  //   return ++this.value
  // },
  [Symbol.toPrimitive](hint) {
    console.log(hint);//转换的类型
    return ++this.value
  }
}

if (a == 1 && a == 2 && a == 3) {
  console.log('ok');

}

全等(===):严格等于不会进行隐式转换,这里使用 Object.defineProperty 数据劫持的方法来实现

let value = 1;
Object.defineProperty(window, 'a', {
    get() {
        return value++
    }
})
if (a === 1 && a === 2 && a === 3) {
    console.log("Hi Libai!")
}
Symbol.toStringTag
Object.prototype.toString.call()

应用: