Symbol能干什么为什么要掌握它

16次阅读

共计 2193 个字符,预计需要花费 6 分钟才能阅读完成。

说到 Symbol 就先来说下 js 中的基础数据类型 string、number、boolean、null、undefined,Symbol 就是 js 中的第六种基础数据类型

用一句话来描述 Symbol, 那就是独一无二!

Symbol 的使用

基本使用

const s1 = Symbol('song');
const s2 = Symbol('song');
// Symbol 中的标识一般放 number、string
console.log(s1 === s2); // Symbol 声明的变量不相等

Symbol 作为 key

    const s1 = Symbol('song');
    let obj = {[s1]:'song', // es6 语法 [] 可以将 symbol 的值作为属性
        age:18
    }
    for(let key in obj){ // for 循环无法遍历 symbol 属性
        console.log(obj[key])
    }
    // Reflect.ownKeys 方法可以拿到所有的 key 属性
    Reflect.ownKeys(obj).forEach(key=>{console.log(obj[key]);
    })

Symbol.for

我们上面说 symbol 是独一无二的, 但是有的时候我希望可以复用声明过的 symbol,可以使用 for 语法,如果 symbol 不存在则声明,如果存在则将创建过的 symbol 返回回来!

const s1 = Symbol.for('song');
const s2 = Symbol.for('song');

console.log(s1 === s2);
console.log(Symbol.keyFor(s2)); // 可以通过 keyFor 获取 symbok 的 key

Symbol 元编程


元编程:可以去对原生 js 的操作进行修改,说白了就是可以更改原生 js 的行为

ES6 提供了 11 个内置的 Symbol 值

1.Symbol.hasInstance

重写 instanceof 默认行为

const instance = {[Symbol.hasInstance](value){return 'a' in value}
}
// 当调用 instanceof 方法,会默认调用 instance 上的 hasInstance 方法
console.log({a:1} instanceof instance)

2.Symbol.isConcatSpreadable

重写数组的展开行为

const arr = [1,2,3];
arr[Symbol.isConcatSpreadable] = false;
console.log(arr.concat([1,2,3]));

3.Symbol.match / split / search / replace

重写字符串的 match,split,search 方法

const obj = {[Symbol.match](value){return value.length === 3}
}
console.log('abc'.match(obj));

4.Symbol.species

创建衍生对象时, 指定构造函数

class MyArray extends Array{constructor(...args){super(...args);
    }
    static get [Symbol.species](){return Array; // 创建衍生对象会用 Array 作为构造函数}
}
const arr = new MyArray(1,2,3);
const newArr = arr.map(item=>item*2);
console.log(newArr instanceof MyArray); // 默认衍生对象也是 MyArray 的实例

5.Symbol.toPrimitive

重写数据类型转化

const obj = {[Symbol.toPrimitive](type){ // type number string default
        return 123;
    }
}
console.log(obj*123);

6.Symbol.toStringTag

重写 toString 方法

const obj = {[Symbol.toStringTag]: "xxx"
};
console.log(Object.prototype.toString.call(obj)); // [object xxx]

7.Symbol.unscopables

重写哪些属性被 with 所排除

console.log(Array.prototype[Symbol.unscopables]); // 哪些方法不能再 with 中使用
with(Array.prototype){ // 直接调用数组原型上的方法
    forEach.call([1,2,3],element => {console.log(element)
    });
}

class MyClass {eat() {}
  get [Symbol.unscopables]() {return { eat: true}; // 不能在 with 下使用
  }
}
with (MyClass.prototype) {console.log(eat);
}


还差最后一个 Symbol.iterator,留个小尾巴,大家自己踩一踩看看这个有什么用!!这个面试经常会被问哦~

到此我们将 Symbol 的用法整个过了一遍,当然一般元编程在开发的时候还是很少用到呢!不过我们已经具备改写 js 语言本身的能力啦!

` 欢迎持续关注公众号:「前端优选」
技术持续更新,请持续关注 ……`

正文完
 0