js中的this

js中的this引用的是函数据以执行的环境对象,而js教程中所说的环境对象分为全局环境和函数所定义的局部环境,那么以下代码中

var color = 'red';
function showColor() {
    console.log(this.color);
}
showColor();  // 'red',因为this指向window
var o = {
    color: 'blue'
};
o.showColor = showColor;
o.showColor(); // 'blue' ????这里的this指向的是o?o也可以构成一个执行环境?
阅读 3.7k
6 个回答

“js中的this引用的是函数据以执行的环境对象”这句话拓展一下:
js中的this有四种调用模式:
1.方法调用模式:当一个函数被保存为一个对象的属性,这个方法被调用时,this指向该对象。[此题应该是作为对象的方法调用的]
2.函数调用模式:当一个函数直接被调用(不是作为一个对象的方法被调用)。[我想你是把第一种和这种搞混了]
(剩下两种参照《JavaScript语言精髓》这本书吧^_^)
3.构造器调用模式:
4.apply调用模式:

有一个不变的道理,什么对象调用了showColor,那么this便指向那个对象。

var color = 'red';
function showColor() {
    console.log(this.color);
}
showColor();  // 相当于window.showColor()
var o = {
    color: 'blue'
};
o.showColor = showColor;
o.showColor(); //o.color === 'blue',o调用了showColor,那么this便指向o

JS中的this,大体有以下几种取值:

  • 全局范围

console.log(this); //全局变量

全局范围使用this指向的是全局变量,浏览器环境下就是window。
注:strict模式不存在全局变量,这里的this是undefined。

  • 函数调用

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

foo(); //全局变量

函数调用中的this也指向全局变量。
注:strict模式不存在全局变量,这里的this是undefined。

  • 对象方法调用

var test = {
    foo: function () {
        console.log(this);
    }
}

test.foo(); //test对象

对象方法调用中,this指向调用者。

var test = {
    foo: function () {
        console.log(this);
    }
}

var test2 = test.foo;
test2();  //全局变量

不过由于this的晚绑定特性,在上例的情况中this将指向全局变量,相当于直接调用函数。
这点非常重要,同样的代码段,只有在运行时才能确定this指向。

  • 构造函数

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

new Foo(); //新创建的对象
console.log(foo);

在构造函数内部,this指向新创建的对象。

  • 显式设置this

function foo(a, b) {
    console.log(this);
}

var bar = {};

foo.apply(bar, [1, 2]); //bar
foo.call(1, 2); //Number对象

使用Function.prototype的call或者apply方法时,函数内部this会被设置为传入的第一个参数。

如果使用面向对象的思路来理解的话。
第一个调用showColor()中的this指向的是window是因为,
在全局环境中调用showColor就相当于window.showColor()
这个全局对象windows有自己的成员colorshowColor方法

window = {
    color: 'red',
    showColor: function() {console.log(this.color)};
}

类似

class Window {
    public String color;
    public void showColor() {
        console.log(this.color); //this当然是指向实例对象了
    }
}
window = new Window(); //new Window("red");
window.showColor(); //showColor();

类推应该不难理解了。

你问题中的第一句话的理解是错误的。

你把“环境”(当前环境以及外部环境)和this搞混了,它们俩不是一回事。

外部环境是函数定义时确定的,函数有个内部属性[[scope]]就是用来保存它的,题目中两次都是window;而this是函数执行时确定的,由调用方式确定的。具体你可以看一下ES规范函数调用表达式的执行过程那一章节。

http://www.ecma-international.org/ecma-262/5.1/index.html#sec-11.2.3

请牢牢记住这句话:

外部环境是函数定义时确定的,this是函数执行时确定的。他俩不是一回事儿。

@老徐不二 的理解在这个例子来说虽然是不错的,但是建议不要这么理解。
不然,随着学习的慢慢深入,你会发现越来越多的抓破脑皮也想不清楚的this指向问题。因此建议针对javascript中this的问题,要认真的对待,当成一个大问题去解决他。不要贪便宜简单随便理解一下。

关于this指向的分类,网上有很多前辈都写了很好的博客文章,建议多看看。
根据我自己的经验,this的理解,总的来说就是要结合上下文语境来说。

什么叫做结合上下文语境?
比如在中文中,我们说“我”字。

我:“我中午要吃炸鸡!”;
我朋友转述给另外的朋友1:“xx说,他中午要吃炸鸡!”
我朋友转述给另外的朋友2:“xx说:‘我中午要吃炸鸡!’”
// 仅仅解释结合上下文语境的意思,与js中this无关

理解了什么叫做结合上下文,那么,下面这一篇文章则是我必须要推荐给大家的文章了。
在文中,题主不仅可以找到自己这个例子,还能看到更多的例子,希望能帮到你!
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题