闭包的this为何指向全局

zp1996
  • 3.2k
var x = 10;
function foo () {
    function fun () {
        return this.x;
    }
    console.log(fun());
}
foo();

这个很清楚的就是this指向是全局,但是为什么指向的是全局呢?

问题的关键就是函数调用模式即通常的函数调用,属于全局性调用,此时this对应的是全局对象,即Window对象,这里的属于全局性调用如何理解?

评论
阅读 2.4k
5 个回答
✓ 已被采纳

JavaScript函数的四种调用方式。当你清楚这四种调用方式后,无论什么关于this的面试题都可以轻松搞定,唯一需要注意的是ES6规范中箭头函数中的this。用手机码字,详细的就不说了,你自行百度或谷歌,JavaScript函数四种调用方式,说不定还能搜到我的博客。


我回来了,用电脑给你回答

那么什么是函数的四种调用模式:关于函数四种调用模式(摘抄自《Javascript语言精髓》)

  • 方法调用模式

  • 函数调用模式

  • 构造器调用模式

  • apply/call调用模式

this在四种调用模式下的意义:

1.方法调用模式
当一个函数被保存为对象的一个属性时,我们称它为一个方法,当一个方法被调用时,this被绑定到该对象。
如果一个调用表达式包含一个属性存取表达式(即一个.点表达式或[]下标表达式),那么它就被当作一个方法来调用。

//创建myObject,它有一个value属性和一个increment方法
//increment方法接受一个可选的参数,如果参数不是数字,那么默认使用数字1

var myObject = {
    value: 0,
    increment: function(inc) {
       this.value += typeof inc === 'number' ? inc : 1;
    }
};

myObject.increment();
console.log(myObject.value); //1
myObject.increment();
console.log(myObject.value); //2

方法可以使用this去访问对象,所以它能从对象中取值和修改该对象。this到对象的绑定发生调用的时候。这个“超级”迟绑定,使得函数可以对this高度复用。通过this取得它们所属对象的上下文的方法称为公共方法。

2.函数调用模式
当一个函数并非一个对象的属性时,那么它被当做一个函数来调用
var sum = add(3, 4);
当函数以此模式调用时,this被绑定到全局对象。这是语言设计上的一个错误

所以当我们在使用回调函数时(回调函数的执行时,如果使用的函数模式调用的话,也可以使用其他模式调用,所以这里的说法不准确),就必须使用下面的技巧去避免这个错误。

所以在我们使用这种函数模式的时候需要注意了:

myObject.double = function() {
     var that = this; //解决上面提到的错误
     var helper = function() {
         that.value = add(that.value, that.value);
     };
     helper(); //以函数模式调用helper。 
};

//以方法模式调用double
myObject.double();
console.log(myObject.value); 

3.构造函数调用模式

Javascript是一门基于原型继承的语言。这意味着对象可以直接从其他对象继承属性。该语言是无类别的
这个偏离了当今语言的主流。大部分语言都是基于类的语言,尽管原型继承有这强大的表现力,但是它不被广泛理解。

如果一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this会被绑定到这个新对象上,new前缀也会改变return语句的行为。

//创建一个名为Quo的构造函数,它构造一个带有status的属性对象
var Quo = function(string) {
    this.status = string;
};

//给Quo的所有实例提供一个名为get_status的公共方法
Quo.prototype.get_status = function() {
    return this.status;
};

//构造一个Quo实例

var myQuo = new Quo("confused");
myQuo.get_status();

4.Apply调用模式

因为Javascript是一门函数式的面向对象编程语言,所以函数可以拥有方法
apply方法让我们构造一个参数的数组并用其去调用的函数。它允许我们选择this的值。
apply方法接收两个参数。第一个将被绑定给this的值,第二个是一个参数数组

var array = [3, 4];
var sum = add.apply(null, array); //7

var statusObject = {
    status: 'A-OK'
};

//statusObject并没有继承自Quo.prototype,但是我们可以在它上面调用
//get_status方法。
var status = Quo.prototype.get_status.apply(statusObject); //"A-OK"

了解了四种调用方式后,就可以解决楼主的问题了,剩下的大家自己想吧!!!

this代表的是执行环境,而题目中的函数的执行环境就是window也就是你说的全局。

记住一句话应该对你理解this的指向有帮助:this指向拥有该function的那个人。foo跟fun只是'嵌套'关系,这里的fun调用的形式就是普通调用,所以拥有它的就是全局的window

this在fun内值的就是fun,它只是当前函数或者对象的一个应用 this.hello = 'hello world'; var _this = this; function() { console.log(_this.hello); }试试

宣传栏