JavaScript:作为函数/方法调用

JavaScript:作为函数/方法调用,javascript,invocation,Javascript,Invocation,我正在努力提高我的JavaScript技能,我知道调用函数有四种基本方法——它们改变了这个的定义方式。我感兴趣的两个是基本的两个: 作为函数调用 作为方法调用 这很好。第一个,此将引用窗口对象: function doSomething() { console.log(this); } doSomething(); // window is logged 第二个这个将引用它正在执行的对象: var t = { doSomething: function () {

我正在努力提高我的JavaScript技能,我知道调用函数有四种基本方法——它们改变了
这个
的定义方式。我感兴趣的两个是基本的两个:

  • 作为函数调用
  • 作为方法调用
这很好。第一个,
将引用
窗口
对象:

function doSomething() {
    console.log(this);
}

doSomething(); // window is logged
第二个
这个
将引用它正在执行的对象:

var t = {
    doSomething: function () {
        console.log(this);
    }
};

t.doSomething(); // t is logged
这很好。但是,在这两个调用方法中,
this
总是返回该方法所包含的对象,这样说是否正确(如果有意义的话)

在第一个示例中,
doSomething()
实际上是在
窗口
对象中定义的,因此是
窗口
对象的属性,即使我们没有定义(或引用它)


因此,在现实中,难道不能说作为函数的调用就是作为方法的调用吗?是否?

想象一下定义函数时,不是像您那样在全局对象的范围内,而是在另一个函数的范围内:

function outer() {
    var inner = function(){console.log(this)};
    inner();
};
outer();
你认为这将意味着什么?将打印什么

您可能认为它将是外部函数对象,但事实证明它将始终是全局对象

就好像你写过:

function outer() {
    var inner = function(){console.log(this)};
    inner.call(window);
};
outer();
这是一个相当危险的和远离直觉的JS“特性”

那么,回到你的第一个例子,你所做的基本上是:

doSomething = function () {
    console.log(this);
}
doSomething().call(window);
而且,正如Yoshi指出的,如果你使用ES5的严格模式,你最终会做类似的事情,在我看来,这远没有那么危险:

doSomething().call(未定义)


它还向您提供了一个强有力的提示,说明您永远不应该在函数中使用此选项;)

参考:对于第一个示例,我们将记录。它大约是
这个
指针。如果您在
object
中声明一个函数,那么我们可以说它是一个方法调用,因为函数现在是对象的一部分,对象被定义为方法。此外,在本例中,
指向对象。若您在窗口中(或不在对象内部)声明函数,那个么它的函数调用,因为现在
这个
指向窗口。