如何用ES5模拟实现ES6的Symbol功能

29 min read

好的,以下是实现代码:

function Symbol(key) {
  if (typeof key !== 'string') {
    throw new TypeError('Symbol description must be a string');
  }
  Object.defineProperty(this, '__description', {
    value: key,
    writable: false,
    enumerable: false,
    configurable: false
  });
}

Object.defineProperty(Symbol.prototype, 'toString', {
  value: function() {
    return 'Symbol(' + this.__description + ')';
  },
  writable: true,
  enumerable: false,
  configurable: true
});

Object.defineProperty(Symbol.prototype, 'valueOf', {
  value: function() {
    return this;
  },
  writable: true,
  enumerable: false,
  configurable: true
});

Symbol.for = function(key) {
  var globalSymbols = window.__globalSymbols || (window.__globalSymbols = {});
  if (globalSymbols[key]) {
    return globalSymbols[key];
  }
  var symbol = new Symbol(key);
  globalSymbols[key] = symbol;
  return symbol;
};

Symbol.keyFor = function(sym) {
  var globalSymbols = window.__globalSymbols || (window.__globalSymbols = {});
  for (var key in globalSymbols) {
    if (globalSymbols[key] === sym) {
      return key;
    }
  }
};

然后可以使用 var mySymbol = new Symbol('mySymbol') 来创建符号,使用 mySymbol.toString()mySymbol.valueOf() 来访问符号,使用 Symbol.for('key') 来创建全局符号。