js -- symbol

111 阅读1分钟

symbol, 表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

以上,摘自 Symbol

总结就是 Symbol

  1. 用来解决属性名冲突的问题,构造唯一的属性名或者变量
  2. 私有属性
function getObj () {
    const symbol = Symbol('test');
    const obj = {};
    obj[symbol] = 'test';
    return obj;
}

question: 具体如何让一个对象可遍历?

// 对象是不能用for...of来遍历的,那这里???
for(const item of obj){
    console.log(item); // 1 2 3 4 5 6 7 8 9 10
}
// 这样处理
const obj = {
    count: 0,
    [Symbol.iterator]: () => {
        return {
            next: () => {
                obj.count++;
                if(obj.count <= 10){
                    return {
                        value: obj.count,
                        done: false
                    }
                }else{
                    return {
                        value: undefined,
                        done: true
                    }
                }
            }
        }
    }
};

question:

  • JSON.stringify 会忽略symbol?除了这个,还会忽略什么?? undefined function
  • 如果对象有循环引用,可以通过JSON.stringify来处理吗?? 会报错
  • 确定是stringify会报错,而不是parse会报错?
  • 实现一个深拷贝
//  JSON.parse(JSON.stringify(obj))

function deepClone (obj, hash = new WeakMap()) { 
    // WeakMap可以用一个对象作为key,但是它不会持有这个对象的引用,弱引用,不会影响内存,垃圾回收等
    if(obj === null){
        return null;
    }
    if(obj instanceof Date){
        return Date;
    }
    if(obj instanceof RegExp){
        return RegExp;
    }
    if(typeof obj !== 'object'){
        return obj;
    }
    if(hash.has(obj)){
        return hash.get(obj);
    }
    const resObj = Array.isArray(obj) ? [] : {};
    hash.set(obj,resObj);
    Reflect.ownKeys(obj).forEach(key => {
        resObj[key] = deepClone(obj[key], hash);
    });
    return resObj;
}

question: 判断对象类型?

通过查找对象的隐式原型 是否严格等于 对应类型的显示原型

以下,实现一个instanceof

function instanceOf (left,right) {
    if(typeof left !== 'object' || left === null){
        return false;
    }
    while(true){
        if(left === null){
            return false;
        }
        if(left.__proto__ === right.prototype){
            return true;
        }
        left = left.__proto__;
    }
}