使用Javascript实现Symbol

    

使用Javascript实现Symbol

// 当调用 Symbol 的时候,会采用以下步骤:
//1. 如果使用 new ,就报错
//2. 如果 description 是 undefined,让 descString 为 undefined
//3. 否则 让 descString 为 ToString(description)
//4. 如果报错,就返回
//5. 返回一个新的唯一的 Symbol 值,它的内部属性 [[Description]] 值为 descString
(function () {
    var root = this;
    var generateName = (function () {
        var postfix = 0;
        return function (descString) {
            postfix++;
            return '@@' + descString + '_' + postfix
        }
    })()
    var SymbolPolyfill = function Symbol(description) {
        // 实现特性第 2 点:Symbol 函数前不能使用 new 命令
        if (this instanceof SymbolPolyfill) throw new TypeError('Symbol is not a constructor');
        // 实现特性第 5 点:
        // 如果 Symbol 的参数是一个对象,toString 方法,将其转为字符串,然后才生成一个 Symbol 值。
        var descString = description === undefined ? undefined : String(descString);
        var symbol = Object.create({
            toString: function () {
                return this.__Name__;
            },
            valueOf: function () {
                return this;
            }
        })
        // 语法: Object.defineProperties(obj, props)
        // obj: 将要被添加属性或修改属性的对象
        // props: 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
        Object.defineProperties(symbol, {
            '__Description__': {
                value: descString,
                writable: false,
                enumerable: false,
                configurable: false
            },
            '__Name__': {
                value: generateName(descString),
                writable: false,
                enumerable: false,
                configurable: false
            }
        })
        // 实现特性第 6 点,因为调用该方法,返回的是一个新对象,两个对象之间,只要引用不同,就不会相同
        //  Symbol 函数的参数只是表示对当前 Symbol 值的描述,相同参数的 Symbol 函数的返回值是不相等的。
        return symbol
    }
    var forMap = {};
    // Symbol.keyFor 方法返回一个已登记的 Symbol 类型值的 key
    Object.defineProperties(SymbolPolyfill, {
        'for': {
            value: function (description) {
                var descString = description === undefined ? undefined : String(description)
                return forMap[descString] ? forMap[descString] : forMap[descString] = SymbolPolyfill(descString);
            },
            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
        }
    })
    root.SymbolPolyfill = SymbolPolyfill
})();

所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站部分内容收集于互联网,如果有侵权内容、不妥之处,请联系我们删除。敬请谅解!

添加新评论

  关于博主

QQ:1960727927
E-Mail:ceet@vip.qq.com
个人主页:https://aiylqy.com
个性签名:毁掉一个人最好的方式就是放纵他的缺点。

  近期评论

有种脾气叫,不放弃。

梦想是注定孤独的旅行,路上少不了质疑和嘲笑,但那又怎样,哪怕遍体鳞伤也要活的漂亮。

不管现在有多么艰辛,我们也要做个生活的舞者。

命运从来不会同情弱者。

不怕万人阻挡在前方,只怕自己先行投降。