我以为我知道 JavaScript 的 this
关键字是如何工作的,但我又被吓了一跳。考虑这个片段:
function foo()
{
return 'Foobar';
}
foo.valueOf = function()
{
return this();//this points to foo
};
foo.toString = foo;//alternatively
console.log(foo + '');//logs Foobar as you'd expect
在valueOf
方法中,this
将指向函数对象,因为我正在定义函数对象的属性。但是当我尝试对 location
对象做同样的事情时:
location.origin = function()
{
return this.protocol + '//' + this.hostname;
};
location.origin.valueOf = location.origin;
location.origin.toString = function()
{
return this();
}
console.log(location.origin + '/uri');//undefined//undefined/uri ?
console.log(location.origin.toString());//undefined//undefined ?
console.log(location.origin.valueOf());//undefined//undefined ?
让它工作的唯一方法是将 this()
更改为 location.origin()
。谁能解释一下 location
对象有什么不同?我可以随意分配属性和方法,但我注意到 Location
构造函数及其原型(prototype)不像其他原型(prototype)那样“可访问”。在 Chrome 中,您必须使用 Object.getPrototypeOf(location);
,而 FF 允许使用 Location.prototype
。
基本上,我有 2 个问题:
上面的 location.origin
和:
var foo = {bar:function(){return 'Foobar';}};
foo.bar.valueOf = function(){return this();};
console.log(foo.bar + '');//logs Foobar!
其次
有没有其他对象有这样的行为?
最佳答案
this
的值完全由函数的调用方式或 Function.prototype.bind 设置。 .
In the valueOf method, this will point to the function object, because I'm defining a property of the function object.
不,不是。在函数中,this
引用 foo
是因为您调用 函数的方式,而不是您定义函数的方式。
> location.origin = function() {
> return this.protocol + '//' + this.hostname;
> };
>
> location.origin.valueOf = location.origin;
请注意,location
是一个宿主对象。在 Safari 中,origin
是只读的,上面什么都不做:
alert(typeof location.origin); // string, not function
Firefox 中的结果不同,如 OP 中所述。
javascript 中的一条黄金法则是:“不要像对待 native 对象一样对待宿主对象”。那是因为它们不一定表现得像本地对象。您观察到的行为与 this
的设置方式无关,而与主机对象及其属性的困惑有关。
关于JavaScript this 关键字惊喜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12531972/