this的不同指向
this总是指向函数的直接调用者(而非间接调用者)- 如果有
new关键字,this指向new出来的那个对象 - 在事件中,
this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象window this关键字是一个非常重要的语法点。记住一点:this不管在什么地方使用,它永远指向一个对象。 下面是一个例子:
var person = {
name: '张三',
describe: function(){
console.log('姓名: ' + this.name)
}
}
person.describe()
上面代码中,this.name表示name属性所在的那个对象。this.name是在describe方法中调用的,而describe方法所在的当前对象是person,因此this.name指向person,this.name就是person.name。
由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可以改变的,所以this的指向也是可变的。
var A = {
name: '张三',
describe: function(){
console.log('姓名: ' + this.name)
}
}
var B = {
name: '李四'
}
B.describe() = A.describe
B.describe()
// '姓名:李四'
上面代码,A.describe属性被赋值给B,于是B.describe()就表示describe方法所在的当前对象B,所以this.name就指向B.name
重构这个例子,this的指向就能看得更清楚
function f(){
console.log('姓名:' + this.name)
}
var A = {
name: '张三',
describe: f
};
var B = {
name: '李四',
describe: f
};
A.describe() //姓名:张三
B.describe() //姓名:李四
上面代码中,函数f内部使用了this关键字,随着函数f所在的对象不同,this的指向也不同。
只要函数被赋给另一个变量,this的指向就会发生改变。
var A = {
name: '张三',
describe: function () {
console.log('姓名:'+ this.name);
}
};
var name = '李四';
var f = A.describe;
f() // "姓名:李四"
上面代码中,A.describe被赋值给变量f,的内部this就会指向f运行时所在的对象。
JavaScript语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象下运行的,this就是函数运行时所在的对象。
this使用场合
(1)全局环境
全局环境使用this,它指的就是顶层对象window。
this === window //true
function f(){
console.log(this === window)
}
f() //true
(2)构造函数
构造函数中的this,指的是实例对象
function F(){
this.hello = function(){
console.log('Hello'+this.name)
}
}
var f1 = new F()
f1.name = '张三'
f1.hello()
var f2 = new F()
f2.name = '刘能'
f2.hello();
(3)对象的方法
方法在哪个对象下,this就指向哪个对象
var o1 = {
s1: '123',
f1:function(){
console.log(this.s1)
}
}
var o2 = {
s1: '456',
f1:o1.f1
}
o2.f1()
JavaScript提供了call,apply,bind这三个方法,来切换/固定this的指向。
call()方法、apply()方法、bind()方法
(1)call()方法
var lisi = {names: 'lisi'};
var zs = {names: 'zhangsan'};
function f(age){
console.log(this.names)
console.log(age)
}
f(23); // undefined
f.call(zs, 32); // zhangsan
call方法使用的语法规则
函数名称.call(obj,arg1,arg2...argN);
参数说明:
obj:函数内this要指向的对象,
arg1,arg2...argN :参数列表,参数与参数之间使用一个逗号隔开
(2)apply()方法
var lisi = {name:'lisi'};
var zs = {name:'zhangsan'};
function f(age,sex){
console.log(this.name+age+sex);
}
f.apply(zs,[23,'nan']);
函数名称.apply(obj,[arg1,arg2...,argN])
参数说明:
obj :this要指向的对象
[arg1,arg2...argN] : 参数列表,但是要求格式为数组
(3)bind()方法
bind方法用于将函数体内的this绑定到具体的某个对象上
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81