关于Symbol一些好玩的东西。
无意间发现,涉及到Symbol的东西一般都比较底层。
先从最简单的讲起。
1、 Symbol.toStringTag
大家肯定都知道toString这个方法,一般都用来查看当前值的类型,就比如
const arr = [];
Object.prototype.toSrting.call(arr); // 类型:[object Array]
那为什么不能用这个值自己的toString方法呢。很显然他们自身的toString方法都被重载了,所以不行。
那Symbol.toStringTag又是干嘛的呢。
注意观察[object Array] 这里面的 Array字段,他就是Symbol.toStringTag提供的。
举个例子;
function fn() {};
Object.prototype.toString.call(fn); // [object Function]
答案是[object Function]显而易见对吧,都知道是通过new Function来实现的。
那么如果修改 Function.prototype[Symbol.toStringTag] = 'SelfType' 会发生什么呢?
再次打印Object.prototype.toString.call(fn); // [object SelfType]
会发现 [object Function] 变成了 [object SelfType];
由此我们可以初步断定,type的控制是由Symbol.toStringTag来控制的。
2、Symbol.iterator
先举个例子
const obj = {obj1: 1, obj2: 2}
const arr = [1, 2]
const [a, b] = obj; // 报错
const [a, b] = arr // 不报错
结果肯定是报错对吧,大致内容提示了我们obj并不是一个可迭代对象,
那为什么arr就可以成功呢。
答案是arr下面有一个属性,就是Symbol.iterator,
我们打印arr[Symbol.iterator]发现是一个函数,
调用后发现是个数组迭代器对象,下面就有我们熟悉的方法。next()。
那, 我们能不能在obj下面也写一个类型arr[Symbol.iterator]这样的东西呢
obj.__proto__[Symbol.iterator] = function() {
let index = -1;
return {
next: (function() {
index++
return {
value: Object.values(this)[index]
}
}).bind(this)
}
}
这样解构obj也不会报错了,是不是觉得剖开这些原理会特别有意思呢。
参考:developer.mozilla.org/zh-CN/docs/… 参考:developer.mozilla.org/zh-CN/docs/…