据我所知,JavaScript ES6中的Symbol
原语对两件事特别有用:
Object
属性Object
方法,属性和运算符
Symbol.hasInstance
运行instanceof
Symbol.hasInstance
的自定义版本,我们可以覆盖instanceof
的行为我的基本问题是:为什么使用Symbol
来覆盖这些功能?我们不能直接覆盖它们吗?
例如:覆盖String.prototype.match()
而不是Symbol.match
编辑:同意直接覆盖instanceof不起作用的评论者,因此使用match()作为示例。
答案 0 :(得分:3)
在你的问题中你没有详细说明,但从一些推论和评论来看,你似乎误解了众所周知的符号如何与现有类型进行交互。这导致您误解了他们如何改进可能的ES5全球覆盖解决方案。
了解String.match
的值是符号非常重要,而不是匹配功能。这几乎就像某人已经完成了
Symbol.match = Symbol("match");
在程序的顶部创建一个新的Symbol,并将其设置为全局属性,以便任何人都可以从任何地方访问它。
这与String.prototype.match
的值形成对比,"foo".match(...)
是开发人员调用String.prototype.match
时使用的实际函数。
您似乎想象String.prototype.match = function(obj) {
return Symbol.match(obj);
};
喜欢
String.prototype.match = function(obj) {
// Any object that has a `Symbol.match` property
// will just call that property. This includes every
// existing RegExp object.
if (obj != null && obj[Symbol.match] !== undefined) {
return obj[Symbol.match](this);
}
// Otherwise create a new regex to match against
// match match using that. This is to handle strings, e.g
// "foo".match("f")
const reg = new RegExp(obj);
return reg[Symbol.match](this);
};
情况并非如此。查看实际实现的简化示例可以帮助您理解:
obj[Symbol.match](this);
并记住,Symbol.match()
未调用obj
,它正在使用名称 Symbol.match
从var regexp = new RegExp("little");
var result = "a little pattern".match(regexp);
读取一个属性,然后调用由此产生的功能。
为什么使用Symbol来覆盖这些功能?
希望这个例子让这个理由更加清晰。
var regexp = new RegExp("little");
var result = regexp[Symbol.match]("a little pattern");
基本上与做
相同class MyOwnMatcher {
constructor(word) {
this.word = word;
}
[Symbol.match](haystack) {
return haystack.indexOf(this.word);
}
}
var index = "a little pattern".match(new MyOwnMatcher("little"));
// index === 2
那么为什么这很重要?因为现在当您设计API来处理文本时,您并不局限于使用正则表达式。我可以把我自己的整个图书馆作为
var original = String.prototype.match;
String.prototype.match = function(arg) {
if (arg instanceof MyOwnMatcher) return this.indexOf(arg);
return original.apply(this, arguments);
};
最重要的是,我无需更改任何全局变量即可完成此操作。在JS代码中,通常认为修改全局变量是不好的做法,除非您正在填充官方推荐和采用的API。您可以实现上述内容,如
int
但它非常丑陋,容易出错,并且修改了一个不是您自己代码中定义的全局对象。
您基本上可以将众所周知的符号视为实现由单独代码定义的接口的一种方式。