symbol, 表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Symbol 值通过Symbol
函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
注意,Symbol
函数前不能使用new
命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
以上,摘自 Symbol
总结就是 Symbol
- 用来解决属性名冲突的问题,构造唯一的属性名或者变量
- 私有属性
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__;
}
}