Symbol 實現

// 當調用 Symbol 的時候,會採用以下步驟:
//1. 如果使用 new ,就報錯
//2. 如果 description 是 undefined,讓 desc 爲 undefined 否則 讓 descString 爲 ToString(description)
//3. 返回一個新的唯一的 Symbol 值,它的內部屬性 [[Description]] 值爲 descString
// 4 keyFor
let generateName = (function(){
  var postfix = 0
  return function(desc) {
    postfix++
    return '@@' + desc + postfix
  }
})()
function Symbol(description) {
  // 1, 如果使用 new ,就報錯
  if (this instanceof Symbol) {
    return new TypeError('Symbol is not constructor') // 實現第一點不可以使用new 調用
  }
  // 2  3如果 description 是 undefined,讓 desc 爲 undefined 否則 讓 descString 爲 ToString(description)
  let desc = description === undefined ? undefined : String(description)

  let symbol = Object.create({
    toString: function() {
      console.log(this._Name_)
      return this._Name_
    },
    valueOf: function () {
      return this;
    }

  })
  Object.defineProperties(symbol, {
    "_Description_" : {
      value: '',
      writable: false,
      enumerable: false,
      configurable: false
    },
    '_Name_': {
      value: generateName(description),
      writable: false,
      enumerable: false,
      configurable: false
    }
  })
  console.log(symbol)
  //3 因爲調用該方法,返回的是一個新對象,兩個對象之間,只要引用不同,就不會相同
  //  Symbol 函數的參數只是表示對當前 Symbol 值的描述,相同參數的 Symbol 函數的返回值是不相等的
  return symbol
}
var forMap = {};
// Symbol.keyFor 方法返回一個已登記的 Symbol 類型值的 key
Object.defineProperties(Symbol, {
    'for': {
        value: function (description) {
            var descString = description === undefined ? undefined : String(description)
            return forMap[descString] ? forMap[descString] : forMap[descString] = Symbol(descString); // 如果有就直接返回 重新使用同一個Symbol
        },
        writable: true,
        enumerable: false,
        configurable: true
    },
    'keyFor': {
        value: function (symbol) {
            for (var key in forMap) {
                if (forMap[key] === symbol) return key;
            }
        },
        writable: true,
        enumerable: false,
        configurable: true
    }
})


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章