javascript理解之this关键字

this应用场景

在《javaScript语言精粹》这本书中,把 this 出现的场景分为四类,简单的说就是:

  1. 有对象就指向调用对象
  2. 没调用对象就指向全局对象
  3. 用new构造就指向新对象
  4. 通过 apply 或 call 或 bind 来改变 this 的所指。

js中的this

我们要记住:this永远指向函数运行时所在的对象!而不是函数被创建时所在的对象。this对象是在运行时基于函数的执行环境绑定的,在全局环境中,this等于window。使用this是因为在实例化对象时,总是不能确定开发者会使用什么样的变量名。使用this,即可在任意多个地方重用同一个函数。考虑下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
function showColor(){
alert(this.color);
}
var oCar1 = new Object;
oCar1.color = "red";
oCar1.showColor = showColor;

var oCar2 = new Object;
oCar2.color = "blue";
oCar2.showcolor = showcolor;

oCar1.showColor();//输出"red"
oCar2.showColor();//输出"blue"

这段代码中,首先用this定义函数showColor(),然后创建两个对象oCar1和oCar2,一个对象属性被设置为”red”,另一个为blue;两个对象都被赋予了属性showColor,指向原始的showColor()函数,调用每个showColor的方法,oCar1输出red,oCar2输出blue。

作为构造函数调用

所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。

1
2
3
4
5
6
7
8
<script type="text/javascript">
function test(){
this.x = 10;
}

var obj = new test();
alert(obj.x); //弹出 10
</script>

全局环境中的this

在看下面一个this出现在全局环境中的例子:

1
2
3
4
5
6
7
8
<script type="text/javascript">
var name = "全局";
function getName(){
var name = "局部";
return this.name;
};
alert(getName());//弹出 全局;
</script>

函数getName()所处的对象是window对象,因此this也一定在window对象中。此时的this指向window对象,所以getName()返回的this.name其实是window.name,因此alert出全局。
结论:无论this身处何处,一定要找到函数运行时(或者说在何处被调用 了)的位置。

局部环境中的this

看下面一个this出现在局部环境中的例子

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
var name = "全局";

var jubu={
name:"局部",
getName:function(){
return this.name;
}
};
alert(jubu.getName());
</script>


函数getName所在的对象是jubu,因此this的安身之处定然在jubu,即指向jubu对象,则getName返回的this.name其实是jubu.name,因此alert出来的是“局部”。

作用域链中的this

1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
function scoping () {
console.log(this);

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

scoping()();
>>window
>> window
</script>

因为scoping函数属于window对象,自然作用域链中的函数也属于window对象。

对象中的this

可以在对象的任何方法中使用this来访问该对象的属性。这与用new得到的实例是不一样的。

1
2
3
4
5
6
7
8
var obj = {
foo: "test",
bar: function () {
console.log(this.foo);
}
};

obj.bar(); // "test"

重写this

无法重写this,因为它是一个关键字。

1
2
3
function test () {
var this = {}; // Uncaught SyntaxError: Unexpected token this
}

apply 和 call 调用以及 bind 绑定

apply 和 call 调用以及 bind 绑定都是指向绑定的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
var bar = {
value: 'huang',
ages: 10
};
function foo(){
console.log(this);
}
console.log(foo());//window,函数没有所属对象:指向全局对象
console.log(foo.apply(bar));//即bar.foo(),this指向了bar,所以能读取该对象的所有属性
console.log(foo.call(bar));//ages: 10 value: "huang" __proto__: Object

var newFoo = foo.bind(bar);
console.log(newFoo());//Object
</script>

jquery中的this

$()生成的是什么呢?实际上$()=jquery(),那么也就是说返回的是一个jquery的对象。
$(this)是jquery对象,能调用jquery的方法,例如click(), keyup()。

1
2
3
4
5
6
 $(function () {
$('button').click(function () {
alert(this);//this 表示原生的DOM
//$(this)表示当前对象,这里指的是button
})
});

在许多情况下JQuery的this都指向HTML元素节点。

结论:
this,表示当前的上下文对象是一个html DOM对象,可以调用html对象所拥有的属性,方法。
$(this),代表的上下文对象是一个jquery的上下文对象,可以调用jquery的方法和属性值。


转自:http://segmentfault.com/a/1190000000660679