JavaScript关键字this用法说明

JavaScript中this出现的场景主要分为如下四类:
1、通过函数名直接调用,this指向window对象。
2、通告对象.函数名调用,this指向该对象(函数作为数组的一个元素,通过数组下标调用的:this指向这个数组)。
3、使用new关键字创建对象,this指向新创建的对象。
4、通告apply、call、bind改变this的指向。
一、通过函数名称直接调用:

function GetName(){
    this.name ="robbin";
    console.log(this.name);
}
GetName();//this指向window对象。

//为了说明this指向全局window对象,我们修改一下
 var name = "sandy";
 function GetName() {
     console.log(this.name);
}
GetName();
function GetName() {
    this.name="robbin";
}
GetName();
console.log(name);

二、函数作为对象的方法调用,此时this指向这个上级对象或者说代用对象。

 function run() {
      alert(this.name+"开始跑");
 }
var person = {
     name:"robbin"
 };
person.run = run;
person.run();

三、通过new关键字创建对象,this指向新创建的对象,

function Person(){
    this.name = "robbin";
}
var person = new Person();
alert(person.name);
//改变一下
var name = "sandy";
function Person(){
    this.name="robbin";
}
var person = new Person();
alert(name);

四、通过apply、call、bind改变this
this本身是不可变的,但是 JavaScript中提供了call/apply/bind三个函数来在函数调用时设置this的值;apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。

var x = 0;
  function test(){
    alert(this.x);
  }
  var o={};
  o.x = 1;
  o.m = test;
  o.m.apply(); //0

apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。
如果把最后一行代码修改为
o.m.apply(o); //1
运行结果就变成了1,证明了这时this代表的是对象o。

另外
DOM event handler
当一个函数被当作event handler的时候,this会被设置为触发事件的页面元素(element)。

var body = document.getElementsByTagName("body")[0];
body.addEventListener("click", function(){
    console.log(this);
});
// <body>…</body>

In-line event handler
当代码通过in-line handler执行的时候,this同样指向拥有该handler的页面元素。

看下面的代码:

document.write('<button onclick="console.log(this)">Show this</button>');
// <button onclick="console.log(this)">Show this</button>
document.write('<button onclick="(function(){console.log(this);})()">Show this</button>');
// window

在第一行代码中,正如上面in-line handler所描述的,this将指向”button”这个element。但是,对于第二行代码中的匿名函数,是一个上下文无关(context-less)的函数,所以this会被默认的设置为window。

前面我们已经介绍过了bind函数,所以,通过下面的修改就能改变上面例子中第二行代码的行为:

document.write('<button onclick="((function(){console.log(this);}).bind(this))()">Show this</button>');
// <button onclick="((function(){console.log(this);}).bind(this))()">Show this</button>

保存this

在JavaScript代码中,同一个上下文中可能会出现多个this,为了使用外层的this,就需要对this进行暂存了。

看下面的例子,根据前面的介绍,在body元素的click handler中,this肯定是指向body这个元素,所以为了使用”greeting”这个方法,就是要对指向bar对象的this进行暂存,这里用了一个self变量。

有了self,我们就可以在click handler中使用bar对象的”greeting”方法了。

当阅读一些JavaScript库代码的时候,如果遇到类似self,me,that的时候,他们可能就是对this的暂存。

var bar = {
    name: "bar",
    body: document.getElementsByTagName("body")[0],

    greeting: function(){
        console.log("Hi there, I'm " + this + ":" + this.name);
    },

    anotherMethod: function () {
        var self = this;
        this.body.addEventListener("click", function(){
            self.greeting();
        });
    }
};

bar.anotherMethod();
// Hi there, I'm [object Object]:bar

同样,对于上面的例子,也可以使用bind来设置this达到相同的效果。

var bar = {
    name: "bar",
    body: document.getElementsByTagName("body")[0],

    greeting: function(){
        console.log("Hi there, I'm " + this + ":" + this.name);
    },

    anotherMethod: function () {
        this.body.addEventListener("click", (function(){
            this.greeting();
        }).bind(this));
    }
};

bar.anotherMethod();
// Hi there, I'm [object Object]:bar

总结
在函数调用中,this是由激活上下文代码的调用者(caller)来提供的,即调用函数的父上下文(parent context ),也就是说this取决于调用函数的方式,指向调用时所在函数所绑定的对象。

总之一句话,this指向谁,不取决于在什么地方定义,而取决于在什么地方调用。谁调用,this就指向谁(上下文对象)。**

Example01

var context = "global";

var obj = {  
    context: "object",
    method: function () {  
        console.log(this + ":" +this.context);

        function f() {
            var context = "function";
            console.log(this + ":" +this.context); 
        };
        f(); 

        (function(){
            var context = "function";
            console.log(this + ":" +this.context); 
        })();
    }
};

obj.method();
// [object Object]:object
// [object Window]:global
// [object Window]:global

对于有些没有上下文的函数,也就是说这些函数没有绑定到特定的对象上,那么这些上下文无关的函数将会被默认的绑定到global object上。

在这个例子中,函数f和匿名函数表达式在被调用的过程中并没有被关联到任何对象,所以他们的this都代表global object。

参考:
http://www.cnblogs.com/wilber2013/p/4909505.html
http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值