Javascript 在Array.filter中使用Set.has-接收器不兼容
假设我有一个Javascript 在Array.filter中使用Set.has-接收器不兼容,javascript,this,Javascript,This,假设我有一个集作为查找表 const myset = new Set(["key1", "key2", "key3", "keepMe"]); 我想过滤myset中的其他一些键(比如mykeys)的另一个数组 const mykeys = ["ignoreMe", "keepMe", "ignoreMeToo", "key2"]; 问题: 为什么我必须使用 const filtered = mykeys.filter(k => myset.has(k)) 而不是 const filt
集
作为查找表
const myset = new Set(["key1", "key2", "key3", "keepMe"]);
我想过滤myset
中的其他一些键(比如mykeys
)的另一个数组
const mykeys = ["ignoreMe", "keepMe", "ignoreMeToo", "key2"];
问题:
为什么我必须使用
const filtered = mykeys.filter(k => myset.has(k))
而不是
const filtered = mykeys.filter(myset.has)
// TypeError: Method Set.prototype.has called on incompatible receiver undefined
i、 例如,为什么我必须在过滤器中创建匿名lambda函数<代码>键。has具有相同的签名(参数-元素,返回布尔值)。一位朋友告诉我这与这个有关
而mykeys.map(console.log)
工作正常(尽管没有太多用处)
我遇到了这个问题,但我仍然不明白为什么“'myset'没有被捕获为这个”。我理解解决方法,但不理解“为什么”。有人能用人性化的方式解释一下吗
更新:谢谢大家的回复。也许我不清楚我在问什么。我确实了解解决办法
@查利特夫明白了。这是我要找的东西:
因为filter()没有隐式this
,其中asset.has
需要有适当的this
上下文。在匿名函数内调用它并手动添加参数使调用自包含
这是一个基本的设计决策,可以追溯到JavaScript语言的第一个定义
考虑一个对象
var myObjet = {
someValue: 0,
someFunction: function() {
return this.someValue;
}
};
现在,当你写作的时候
var myValue = myObject.someValue;
var myFunction = myObject.someValue;
你得到的正是你放进去的东西,就像你写的一样
var myValue = 0;
var myFunction = (function() {
return this.someValue;
});
console.log(this.someValue);
同样,当你写作时
var myValue = myObject.someValue;
var myFunction = myObject.someValue;
你得到的正是你放进去的东西,就像你写的一样
var myValue = 0;
var myFunction = (function() {
return this.someValue;
});
console.log(this.someValue);
…除了现在,你不再在一个对象中。所以这并不意味着什么。的确,如果你尝试的话
console.log(myFunction());
你会看到
undefined
就像你写的一样
var myValue = 0;
var myFunction = (function() {
return this.someValue;
});
console.log(this.someValue);
在任何物体之外
那么,这是什么?JavaScript的决定如下:
- 如果您编写
myObject.myFunction()
,那么在执行myFunction()
部分时,这个
就是myObject
- 如果您只编写
myFunction()
,那么这个
就是当前的全局对象,它通常是window
(并不总是有很多特殊情况)
- 许多函数可以在另一个函数中插入
此
(例如调用
,应用
,映射
,…)
现在,它为什么要这样做?答案是,这对于原型来说是必要的。事实上,如果你现在定义
var myDerivedObject = Object.create(myObject);
myDerivedObjet.someValue = 42;
现在,您有了一个基于myObject
的对象,但具有不同的属性
someValue
console.log(myObject.someFunction()); // Shows 0
console.log(myDerivedObject.someFunction()); // Shows 42
这是因为myObject.someFunction()
将myObject
用于this
,而myDerivedObject.someFunction()
将myDerivedObject
用于this
如果在定义someFunction
的过程中捕获了this
,我们将在两行中都获得0
,但这也会降低原型的有用性。您可以将thisArg
与集合一起使用,的原型具有
作为回调
此模式不需要将的实例绑定到原型,因为
如果将thisArg
参数提供给filter
,它将用作回调函数的此
值。否则,值未定义
将用作其此值。此
值最终可由回调
观察到,该值根据以下条件确定
const
myset=新集合([“键1”、“键2”、“键3”、“keepMe”),
mykeys=[“ignoreMe”、“keepMe”、“ignoreMeToo”、“key2”],
filtered=mykeys.filter(Set.prototype.has,myset);
console.log(过滤)代码>尝试mykeys.filter(myset.has.bind(myset))
。。。这实际上比使用匿名箭头函数更需要编写。我了解解决方法。但是我想知道“为什么”部分:)看看这是否有帮助,因为filter()没有隐式的this
where-as-set.has需要有适当的this
上下文。在匿名函数中调用它并手动添加参数会使调用自包含“为什么”…谁知道呢。只需要知道它是如何工作的谢谢你提醒我关于thisArg
的存在。我会更新我的问题,因为这不是我想要的:)