关于this

JavaScript中this一直是比较奇怪的,并不像java那样静态绑定当前对象。
那JavaScript的this到底是怎么定义的呢?

定义

The this keyword evaluates to the value of the ThisBinding of the current execution context. The this value depends on the callerand the type of code being executed and is determined when control enters the execution context. Thethis value associated with an execution context is immutable. (ECMA-3)

也就是说this是可执行代码类型有关系,在进入执行上下文时确定,而且不可改变。

全局上下文 ##

在全局上下文中,this指向全局对象本身。

console.log(this.document === document); // true

// In web browsers, the window object is also the global object:
console.log(this === window); // true

this.a = 37;
console.log(window.a); // 37

函数上下文

在函数内部,this的值由函数调用方式决定。

1简单调用

function f1(){
  return this;
}

f1() === window; // global object

2作为对象的方法调用

var o = {
    prop: 37,
    f: function() {
        return this.prop;
    }
};
console.log(o.f()); // logs 37

this指向o对象,即当前对象。

3作为构造函数

/*
 * Constructors work like this:
 *
 * function MyConstructor(){
 *   // Actual function body code goes here.  Create properties on |this| as
 *   // desired by assigning to them.  E.g.,
 *   this.fum = "nom";
 *   // et cetera...
 *
 *   // If the function has a return statement that returns an object, that
 *   // object will be the result of the |new| expression.  Otherwise, the
 *   // result of the expression is the object currently bound to |this|
 *   // (i.e., the common case most usually seen).
 * }
 */

function C(){
    this.a = 37;
}

var o = new C();
console.log(o.a); // logs 37


function C2(){
    this.a = 37;
    return {a:38};
}

o = new C2();
console.log(o.a); // logs 38

4使用call和apply设置this

在函数原型中定义的两个方法(因此所有的函数都可以访问它)允许去手动设置函数调用的this值。它们是.apply和.call方法。他们用接受的第一个参数作为this值,this 在调用的作用域中使用。这两个方法的区别很小,对于.apply,第二个参数必须是数组(或者是类似数组的对象,如arguments,反过来,.call能接受任何参数。两个方法必须的参数是第一个——this。

var b = 10;

function a(c) {
  alert(this.b);
  alert(c);
}

a(20); // this === global, this.b == 10, c == 20

a.call({b: 20}, 30); // this === {b: 20}, this.b == 20, c == 30
a.apply({b: 30}, [40]) // this === {b: 30}, this.b == 30, c == 40


blog comments powered by Disqus

Published

19 March 2014

Category

javaScript

Tags