Javascript:为什么;这";内部私有函数指的是全局范围?

Javascript:为什么;这";内部私有函数指的是全局范围?,javascript,scope,this,Javascript,Scope,This,考虑以下代码: function A() {} A.prototype.go = function() { console.log(this); //A { go=function()} var f = function() { console.log(this); //Window }; f(); } var a = new A(); a.go(); 为什么函数“f”中的“this”指的是全局范围

考虑以下代码:

function A() {}    

A.prototype.go = function() {
    console.log(this); //A { go=function()}

    var f = function() {
         console.log(this);  //Window              
    };

    f();
}

var a = new A();
a.go();

为什么函数“f”中的“this”指的是全局范围?为什么它不是函数“A”的作用域?

原因是您将
f
作为
函数而不是
方法调用。当作为函数调用时,
在目标执行期间设置为
窗口

// Method invocation.  Invoking a member (go) of an object (a).  Hence 
// inside "go" this === a
a.go();

// Function invocation. Invoking a function directly and not as a member
// of an object.  Hence inside "f" this === window
f(); 

// Function invocation. 
var example = a.go;
example();

所有功能的范围都是
窗口

要避免这种情况,您可以这样做:

function A() {}    

A.prototype.go = function() {
    var self = this;
    console.log(self); //A { go=function()}
    var f = function() {
         console.log(self);  //A { go=function()}           
    };

    f();
}

JavaScript对这个
特殊名称所指的内容有不同的概念 与大多数其他编程语言相比。总共有五种不同的
的值在语言中绑定的方式

全球范围 在全局范围内使用
时,它将仅引用全局对象

调用函数 此处,
将再次引用全局对象

ES5注意:在严格模式下,全局案例不再存在。
在这种情况下,此
的值将改为
未定义

调用方法 在本例中,
将参考
测试

调用构造函数 前面带有
new
关键字的函数调用充当 构造器。在函数内部,
将引用 到新创建的
对象

的显式设置 使用
调用
应用
函数的方法时。prototype
的值
在被调用函数中显式地将设置为第一个参数 对应函数调用的

因此,在上述示例中,方法案例不适用,而
foo
的内部将设置为
bar

注意:
不能用于引用
对象内部的对象
字面意义的。因此
var obj={me:this}
导致
me
引用
obj
,因为
仅受所列五种情况之一的约束

常见陷阱 虽然这些案例中的大多数都有道理,但第一个案例将被视为另一个案例 语言的错误设计,因为它从来没有任何实际用途

Foo.method = function() {
    function test() {
        // this is set to the global object
    }
    test();
}
一个常见的误解是
这个
内部的
测试
指的是
Foo
;在 事实上,它不是

为了从
test
中访问
Foo
,需要创建一个
method
中的局部变量,它指的是
Foo

Foo.method = function() {
    var that = this;
    function test() {
        // Use that instead of this here
    }
    test();
}
只是一个普通变量名,但它通常用于引用 外部
。结合闭包,它还可以 用于传递

分配方法 另一件在JavaScript中不起作用的事情是函数别名,它是 将方法分配给变量

var test = someObject.methodTest;
test();
由于第一种情况,
test
现在起到普通函数调用的作用;所以,,
它里面的这个
将不再指
someObject

虽然
这个
的后期绑定一开始似乎是个坏主意,但在 事实上,正是这一点使得原型继承起作用

function Foo() {}
Foo.prototype.method = function() {};

function Bar() {}
Bar.prototype = Foo.prototype;

new Bar().method();
当对
的实例调用
方法
时,
现在将引用该方法 举个例子

免责声明:Shamelessy从我自己的资源

中被盗,因为函数
f()
在没有任何对象引用的情况下不会被调用。试试看

f.apply(this);

让我困惑的是,我使用var定义了函数“f”。我是否错误地认为“f”将获得函数A的范围?或者var仅定义我可以在“A”函数中使用此函数?
仅在类的方法中不引用窗口,而不仅仅是常规函数。如果有窗口,则它是
窗口
。在其他JavaScript上下文中,
窗口
未定义(NodeJS、谷歌的V8引擎等),谢谢!非常感谢。好吧,你说这只是“语言的错误设计”。它真的回答了这个问题吗?或者在设计JS时,这种行为背后有什么想法?汉隆剃须刀适用于这种情况吗?它真的那么简单吗?
Foo.method = function() {
    function test() {
        // this is set to the global object
    }
    test();
}
Foo.method = function() {
    var that = this;
    function test() {
        // Use that instead of this here
    }
    test();
}
var test = someObject.methodTest;
test();
function Foo() {}
Foo.prototype.method = function() {};

function Bar() {}
Bar.prototype = Foo.prototype;

new Bar().method();
f.apply(this);