共计 1282 个字符,预计需要花费 4 分钟才能阅读完成。
由来
ES5 的一个中心主旨是将 JavaScript 中的一些“神奇”的部分暴露出来,并详尽定义了这些开发者们在当时模拟不了的功能。ES6 延续了这个传统,新标准中主要通过在原型链上定义与 Symbol 相关的属性来暴露更多的语言内部逻辑。
MDN 关于 well-known Symbol 描述
Symbol.hasInstance
执行 instanceof 时运行的内部方法。
每个函数都有一个 Symbol.hasInstance 方法,用于确定对象是否为函数实例。该方法被定义在 Function.prototype 中,所有对象都继承了 instanceof 属性的默认行为,且这个方法不可写、不可配置和枚举。
obj instanceof Array;
// 等同于
Array[Symbol.hasInstance](obj);
怎么改写一个不可写的属性呢?这个要使用 Object.defineProperty()这个方法了。可以通过以下方法进行改写 instanceof 方法实现。
function SObject() {}
Object.defineProperty(SObject, Symbol.hasInstance, {value: function(v) {return false;}
});
let obj = new SObject();
console.log(obj instanceof SObject); //false
Symbol.isConcatSpreadable
对于数组对象,默认情况下,用于 concat 时,会按数组元素展开然后进行连接(数组元素作为新数组的元素)。重置 Symbol.isConcatSpreadable 可以改变默认行为。
对于类似数组的对象,用于 concat 时,该对象整体作为新数组的元素,重置 Symbol.isConcatSpreadable 可改变默认行为。
let collection = {
0: "Hello",
1: "world",
length: 2,
[Symbol.isConcatSpreadable]: true
}
let messages = ["Hi"].concat(collection);
console.log(messages.length); // 3
console.log(messages); // (3) ["Hi", "Hello", "world"]
var alpha = ['a', 'b', 'c'],
numeric = [1, 2, 3];
numeric[Symbol.isConcatSpreadable] = false;
var alphaNumeric = alpha.concat(numeric);
console.log(alphaNumeric); // 结果: ['a', 'b', 'c', [1, 2, 3] ]
是不是很神奇?我们现在可以编辑影响一些内部函数了!
还有更多内部暴露的方法。
与 string 相关的 Symbol.match、Symbol.replace、Symbol.search 和 Symbol.split
Symbol.toPrimitive 类型转换
Symbol.toStringTag
更多属性参考 MDN
正文完
发表至: javascript
2019-07-13