1

我们知道,this对象是在运行时基于执行函数的执行环境绑定:在全局函数中,this等于window,而当函数被当做某个对象的方法调用时,this等于那个对象。

this的使用环境分以下几种情况:

  • 普通函数调用
  • 作为构造函数调用
  • 作为对象的方法来调用
  • call/apply/bind方法的调用

普通函数调用

单纯函数调用属于全局调用,this指向this指向Global对象,在浏览器着就是window对象。

var name = "the window";
function fn(){
    alert(this.name);
}
fn();    //the window

这个例子很好理解。在全局作用域中声明的变量、函数,都会变成window对象的属性、方法,this指向window

var length = 10
function fn(){
    alert(this.length)
}
var obj = {
    length: 5,
    method: function(fn) {
        fn() // ?
        arguments[0]() // ?
    }
}
obj.method(fn)      //10  1

这个例子就不太好理解了。这里fn依然是单纯的函数调用,我们知道,每个函数在被调用时,都会自动取得两个特殊变量:this和arguments。内部函数搜索这两个变量时,只会搜索到其活动对象为止。所以这里fn中的this指向window。
另外要注意arguments是一个对象,对象属于除了点操作符还可以用中括号,arguments[0]()其实是fn作为arguments对象的方法被调用,this指向arguments,因为参数只有一个fn,因此length为1

var length = 10
var obj = {
    length: 5,
    method: function() {
        function fn(){
            alert(this.length)
        }
        fn();
    }
}
obj.method()     //10

再稍微变换一下代码,this依然指向window

作为对象的方法调用

函数被作为某个方法时,this等于那个对象

var length = 10
function fn(){
    alert(this.length)
}
var obj = {
    length: 5,
    method: fn
}
obj.method()      //5

再换一个例子

function fn(){
    alert(this.length)
}
var obj1 = {
    length: 5,
    method: fn
}
var obj2 = {
    length: 6,
    method: obj1.method
}
obj2.method()      //6

作为构造函数调用

通过new操作符来调用函数,创建一个新的对象,将构造函数的作用域赋予给新对象,因此this指向这个新对象。

var name = "windowName";
function fn(name){
    this.name = name;
    this,sayName = function(){
        alert(this.name);
    }
}
fn("fnName");     //fnName

call/apply/bind方法的调用

这三个方法都是通过传递参数改变函数体内的this。call和apply方法的作用相同,函数体内的this指向的第一个参数。

var name = "window";
var o = {
    name: "object"
};

function fn(){
    alert(this.name)
}

fn.call(this);  //window
fn.call(window);  //window
fn.call(o);       //object
var obj1 = {
    n1:"n1",
    n2:"n2"
};
var obj2 = {
    n1:"nn1",
    n2:"nn2",
    fn:function(x,y){
        this.n1 = x;
        this.n2 = y;
    }
};
obj2.fn.call(obj1,"new1","new2");
console.log(obj1.n1);  //  new1
console.log(obj1.n2);  //  new2
console.log(obj2.n1);  //  nn1
console.log(obj2.n2);  //  nn2

bind方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值

var obj1 = {
    n1:"n1",
    n2:"n2"
};
var obj2 = {
    n1:"nn1",
    n2:"nn2",
    fn:function(x,y){
        this.n1 = x;
        this.n2 = y;
    }
};
var obj = obj2.fn.bind(obj1);
obj("new1","new2");
console.log(obj1.n1);  //  new1
console.log(obj1.n2);  //  new2
console.log(obj2.n1);  //  nn1
console.log(obj2.n2);  //  nn2

参考资料



关注作者吧~

clipboard.png


大米aBigRice
236 声望24 粉丝

欢迎我呀~