Javascript 中的范围和 OR 运算符

Scope and OR operator in Javascript

我今天在写一些 JS 代码时踩到了一些奇怪的东西。

如果 属性 存在,我想执行对象的方法,如果不存在,则执行其他函数。 感觉有点花哨,我写了这样的话:

var obj = {
    method: function(){
        console.log(this);
    }
}

(obj.method || some_other_function)();

如果存在则执行 obj.method,否则执行 some_other_function

但是this关键字在执行obj.method时引用window对象,我完全不知道为什么。
请注意,执行 (obj.method)(); 会给出预期结果(this 指的是我的对象)

显然我不需要这种语法来制作我的代码运行,但我真的很想知道这里发生了什么。

我在这里或其他地方都找不到任何答案,我找到的最接近的答案是 this interesting post,但它没有涵盖这个具体案例。

有人知道那里发生了什么吗?

这里有一个 fiddle 展示了实际情况!

(obj.method || some_other_function)(); 本质上等同于:

var f = obj.method || some_other_function;
f();

在调用它之前,您已通过 运行 将函数从 obj 的上下文中移除。

obj.method()

的语法糖
method.call(obj)

也称为 方法 调用(不同于调用 函数 )。如果 属性 (method) 以任何其他方式使用它 returns 一个函数值。例如。在二进制运算中使用它,例如

(obj.method || some_other_function)()

使它成为一个函数值并且上面的表达式是

的语法糖
(obj.method || some_other_function).call(this)

this 是当前上下文,而不是 obj

(obj.method)() 仍然是一个方法调用,因为 (expression)expression 被视为相等

你的困惑对于学习 JavaScript 的人来说很常见,并且源于对 this 的不完整理解。简短的回答是您的代码正在执行 obj.method()some_other_function()。被调用函数内部 this 的上下文指的是调用该函数的对象。在调用 method 函数(简单调用 obj.method())的典型用例中,obj 调用 method,因此 this 指的是 obj功能块。

但是,表达式 (obj.method || some_other_function)() 似乎没有被任何对象调用,它只是...被调用了,对吧?实际发生的是这个表达式是从全局 space 调用的,在浏览器中,它是 window 对象。所以你可以认为你的代码是这样执行的:

obj : {
    method: function(){
        console.log(this);
    }
}

window.(obj.method || some_other_function)();

some_other_functionobj.method 都是从全局 space 调用的,因为它们被评估为 || 内部的表达式条件块。该表达式实际上只是 window 对象上的 属性,这就是调用它的原因。起初我也对此感到困惑,非常有趣的问题,感谢 Quentin 的正确答案。

这是一篇很棒的博客 post,有助于阐明 JavaScript 中的 thishttp://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

已编辑:我更新了此 post 以反映正确答案,我原来的答案不正确。