JavaScript this指针

this指针,在Java EE等开发语言中叫做“上下文对象”,但是在JavaScript中情况完全不同,不能把Java EE中对this的理解带到JavaScript中来。
言归正传,在JavaScript中,this代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。也就是说this跟函数的声明没有任何关系,只有在函数或者方法被调用时才知道this的值。this关键字会根据环境变化,但是它始终代表的是调用当前函数的那个对象,记住一点:谁调用这个函数或方法,this关键字就指向谁。在JavaScript中函数的调用模式大致分为以下4种:
1、函数调用模式
即一个函数并非某个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下就是window对象。例

function sayName() {
    this.name = "tang";
    console.log(this.name);
}
sayName();//tang

由于this===window对象,上面的写法等同于:

var name = "tang";
function sayName() {
    console.log(this.name);
}
sayName();//tang

注意和下面的写法区分

function sayName() {
    var name = "tang";
    console.log(this.name);
}
sayName();////ReferenceError资源不存在错误(由于在window对象不存在name属性)

2、方法调用模式
当函数是某个对象的属性时,它就可称为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上。例

var name = "window";
var obj = {
    name: "obj",
    sayName: function() {
        console.log(this.name);
    }
};
obj.sayName();  //obj

此时的this指向obj对象
注意和下面的写法区分

var name = "window";
var obj = {
    name: "obj",
    sayName: function() {
        console.log(this.name);
    }
};
var ss = obj.sayName;  
ss();   //window

这种情况相当于在全局作用域调用,是函数调用而不是方法调用!
3、构造函数模式
当函数被作为构造函数调用时(即通过函数new新的函数实例对象),this被绑定到新创建的函数对象上。例

function Obj() {
    this.name = "kxy";
}
var person = new Obj();
console.log(person.name);   //kxy

4、call/apply调用模式
JavaScript中,函数可以通过call和apply方法在特定的执行环境中自调,区别在于call传递多个参数,apply传递参数数组。不管怎么样,这两个函数的第一个参数都是特定的执行环境。下面以apply为例

var name = "window";
var person = {
    name: "kxy"
};
function sayName() {
    console.log(this.name);
}
sayName();    //window
sayName.apply(person);   //kxy(传递person作为执行环境)
sayName.apply();    //window(不传参数是默认的执行环境是全局环境window)

除了上面常见的4中函数调用模式外,还有几种特殊调用,this均指向全局变量window
1、匿名函数调用

var name = "Bob";  
var nameObj ={  
     name : "Tom",  
     showName : function(){  
         alert(this.name);  
     },  
     waitShowName : function(){  
         !function(__callback){
            alert(this.name); 
        }();  
     }  
 };  
 nameObj.showName();   //Tom
 nameObj.waitShowName();  //Bob

2、setTimeout和setInterval

var name = "Bob";  
var nameObj ={  
    name : "Tom",  
    showName : function(){  
        alert(this.name);  
    },  
    waitShowName : function(){
        setTimeout(function(){
            this.showName();
        }, 1000);
    }
}; 

 nameObj.waitShowName();  //Bob

如果想输出期望值,不凡先保存this的值

var name = "Bob";  
var nameObj ={  
    name : "Tom",  
    showName : function(){  
        alert(this.name);  
    },  
    waitShowName : function(){
        var that = this;
        setTimeout(function(){
            that.showName();
        }, 1000);
    }
}; 

 nameObj.waitShowName();  //Tom

无论JavaScript表达式多复杂,嵌套调用多少次,都离不开以上提到的几种情况,只要层层分析,总能得到期望值!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章