学习内容摘自 阮一峰博客
目录
- 涵义
- 使用场合
- 使用注意点
- 绑定this的方法
4.1function.prototype.call()
4.2function.prototype.apply()
4.3function.prototype.bind()
涵义
this关键字是非常重要的语法知识点,如果不理解涵义的话,大部分开发任务都无法完成
首先this总是返回一个对象,简单说们就是返回属性或方法当前所在的对象.
this.property
实际例子
var person = {
name:'张三',
describe:function(){
return '姓名'+this.name;
}
};
person.describe()
//姓名张三
上面代码中,this.name表示describe方法所在的当前对象的name属性,调用person.describe方法时,describe方法所在的当前对象是person,所以就是调用person.name
由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this指向可变的
var a = {
name:'张三',
describe:function(){
return '姓名:'+this.name;
}
};
var b = {
name:'李四'
};
b.haha = a.describe;
b.haha();
//姓名:李四
上面代码中,a.describe属性被赋给b,于是b.describe就表示describe方法所在的当前对象b,所以this.name就指向李四
function f(){
return '姓名:'+this.name;
}
var a = {
name:'张三',
describe:f
}
var b = {
name:'李四',
describe:f
}
a.describe();//姓名:张三
b.describe();//姓名:李四
上面代码中,函数f内部使用了this关键字,随着f所在的对象不同,this指向不同.只要函数被赋值给另一个变量,this指向就会变
var a = {
name:'zhangsna',
describe:function(){
return 'name:'+this.name;
}
};
var f = a.describe;
var name = 'lisi';
console.log(f());
//输出lisi
上面代码中,a.describe函数体赋值给变量f,内部的this就会指向f运行时所在的对象,本例是顶层对象
总结一下,javascript语言之中,一切皆对象,运行环境而是对象,所以函数都是在某个对象之中运行,this就是这个对象(环境).但是javascript支持运行环境动态切换,也就是this指向是动态的,没有办法事先确定到底指向哪个对象.
如果一个函数在全局环境中运行,那么this就是指顶层对象(浏览器中为window对象)
function f(){
return this;
}
f()===window
//true
上面代码中,函数f在全局环境运行,它内部的this就指向顶层对象window.可以近似的认为,this是所有函数运行时的一个隐藏参数,指向函数的运行环境
使用场合
# 构造函数中this 指的是实例对象
var obj = function(p){
this.p = p;
};
Obj.prototype.m=function(){
return this.p;
};
var o = new Obj('hello world');
o.p//hello world
o.m();//hello world
上面代码定义了一个构造函数obj,由于this指向实例对象,所以在构造函数内部定义this.p就相当于定义实例对象有一个p属性,然后m方法可以返回一个p属性
var obj = {
foo:function(){
console.log(this);
}
};
//情况一
obj.foo()//obj
//情况二
(obj.foo=obj.foo)()//window
//情况三
(false||obj.foo)()//window
//情况四
(1,obj.foo)()//window
上面四种情况,只有第一种指向obj后面都指向window
可以这样理解,在javascript引擎内部,obj和obj.foo存储在两个呢不能地址,简称m1,m2.只有obj.foo()这样调用时,是从m1调用m2,因此this指向obj.但是其他三种情况,都是直接取出m2进行计算,然后就在全局环境运算结果(还是m2)因此this指向全局环境
同样的,如果某个方法位于多层对象的内部,这时为了简化书写,把该方法赋值给变量,往往会得到意料之外的结果
var a ={
b:{
m:function(){
console.log(this.p);
},
p:'hello'
}
};
var hello = a.b.m
hello();undefined
原因:上面代码中,m是多层对象内部的一个方法,为求简单,将其赋值给hello变量,结果调用时,this指向了顶层对象,为了避免这个问题,可以只将m所在的对象赋值给hello,这样调用时,this的指向就不会变
var hello = a.b;
hello.m();//hello
或者可以直接连着调用,不要停
a.b.m();//hello
在node中,this指向又分成两种情况,全局环境中,this指向全局对象global;模块环境中,this指向module.exports
//全局环境
this === global //true
//模块环境
this === module.exports//true
使用注意点
- 避免多层this
由于this指向是不确定的,所以切勿在函数中包含多层this
var o = {
f1:function(){
console.log(this);
var f2 = function(){
console.log(this);
}();
}
}
o.f1();
//object;
//window;
上面的代码包含两层this,结果运行后,第一层指向该对象,第二层指向全局对象,实际执行的第三层就相当于全局环境中的一个函数
解决办法两种:
声明变量来取代this,后面一直用这个this
第二种就是使用use strict