this对象是在运行时基于函数的执行环境绑定的。
在全局函数中,this等于window;
而当函数被作为某个对象的方法调用时,this等于那个对象。
1. 全局环境
没有在对象内部定义的函数是全局函数,全局函数和全局变量都是window的对象
var name = 'jero';
function sayName () {
console.log(this.name);
}
sayName() //直接全局调用
window.name; //用window全局对象调用
window.sayName(); //用window全局对象调用
2. 指向调用的对象
var name = 'jero'; //全局变量
function sayName () { //全局函数
console.log(this.name);
}
var obj = { //obj对象
name: 'henry'
};
obj.sayName = sayName; // 给obj对象新增一个sayName方法
obj.sayName() //obj对象调用sayName方法,this指向obj对象,因此name是herry,输出herry。
3. 测试
//定义了全局变量price
var price = 10;
//定义了全局函数getPrice
var getPrice = function () {
return price;
}
//定义了对象apple
var apple = {
price: 8, //apple对象的price属性
getPrice: function () { //apple对象的getPrice方法
return this.price;
}
};
//直接调用全局函数getPrice,得出结果result1
var result1 = getPrice();
//将apple的getPrice方法赋值给全局函数getPrice,相当于重新定义了全局函数getPrice
var getPrice = apple.getPrice;
//直接调用被更新了的全局函数,this指向window,window.price=10,得到result2
var result2 = getPrice()
//调用apple的getPrice方法,因此,this指向apple对象,apple.price=8,得到result3
var result3 = apple.getPrice();
console.log(result1); //10
console.log(result2); //10
console.log(result3); //8
4. 改变this指向的3个方法
(1)bind
(2)call
(2)apply
apply()把参数打包成数组再传入;
call()把参数按顺序传入。
bind()返回一个函数,除此之外和call()传参数情况一样。
比如调用Math.max(3, 5, 4),分别用apply()和call(),bind()实现如下:
对普通函数调用,我们通常把this绑定为null。
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
Math.max.bind(null, 3, 5, 4)(); // 5
下面是一个改变指向的综合例子
//定义了全局变量price
var price = 1;
//定义了对象apple
var apple = {
price: 8, //apple对象的price属性
getPrice: function () { //apple对象的getPrice方法
return this.price;
}
};
//定义了对象orange
var orange = {
price: 10, //orange对象的price属性
getPrice: function () { //orange对象的getPrice方法
return this.price*2;
}
};
var result1 = orange.getPrice();
var result2 = apple.getPrice.apply(orange) //通过apply将this的指向改为orange
var result3 = orange.getPrice.call(this); //通过call将this的指向改为window
var result4 = orange.getPrice.bind(apple)(); //通过bind将this指向改为apple,因为调用bind返回一个新的函数,所以执行语句比前两个多了()
console.log(result1); //20
console.log(result2); //10
console.log(result3); //2
console.log(result4); //16
(1)result1 的值为 20
orange.getPrice 运行时 this 指向 orange, this.price 等于 10, 函数返回 10 * 2 = 20
(2)result2 的值为 10
当前函数体是 apple 的 getPrice, 由于调用时 apply 的参数是 orange, 就是说当前 this 指向的是 orange, this.price 等于 10, 函数返回 this.price, 也就是10。
(3)result3 的值为 2
这里函数体是 orange 的 getPrice, 调用 call 时传的参数是全局的 this, 也就是 window 对象,所以 this.price 等于 1,那么函数运行返回 this.price * 2 的值就是 2。
(4)result4 的值为 16
程序倒数第二行将 apple 作为参数传给 bind 方法,并且将经过 bind 之后的函数覆盖了 orange.getPrice, 那么 orange.getPrice 调用默认的 this 就是指向 apple, 而当前函数体还是 orange 的 getPrice, 所以运行的结果为 8 * 2 = 16
网友评论