Symbol笔记

131 阅读1分钟
  1. for...in...,for of getOwnPropertyNames无法遍历得到对象中的symbol属性名,Object.getOwnPropertySymbols()可以,Reflect.ownKeys()也可以
  2. symbol.for('foo')会搜索全局是否有同样用'foo'创建的symbol,有则返回他,没有则创建(注意这里的创建是全局环境的,无论在哪运行,函数作用域内运行也在全局注册)
let a = symbol.for('123')
let b = symbol.for('123')
a === b //true

function foo(){ 
    let a = Symbol.for('123')
}
foo()
console.log(a) //Symbol(a)
  1. 子iframe注册的symbol父级主窗口也可以直接得到
  2. 可以让node中每个文件导出的实例返回同一个实例(单例),并且不被改写
// mod.js
let  key = Symbol('foo')

function A() {
  this.foo = 'hello';
}

if (!global._foo) {
  global[key] = new A();
}

module.exports = global._foo;

// use.js
global[Symbol('foo')] = {} // 无法覆盖

  1. a instanceOf b实际是调用b[Symbol.hasInstance]
class Even {
  static [Symbol.hasInstance](obj) {
    return Number(obj) % 2 === 0;
  }
}

// 等同于
const Even = {
  [Symbol.hasInstance](obj) {
    return Number(obj) % 2 === 0;
  }
};

1 instanceof Even // false
2 instanceof Even // true
12345 instanceof Even // false
  1. Symbol.isConcatSpreadable控制数组是否可以被concat展开
let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']
arr1[Symbol.isConcatSpreadable] // undefined

let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
  1. 对象进行for...of...循环时,实际调用的是[Symbol.iterator]方法
class Collection {
  *[Symbol.iterator]() {
    let i = 0;
    while(this[i] !== undefined) {
      yield this[i];
      ++i;
    }
  }
}

let myCollection = new Collection();
myCollection[0] = 1;
myCollection[1] = 2;

for(let value of myCollection) {
  console.log(value);
}
// 1
// 2