认识this
在JavaScript中,this是一个比较灵活的关键字,他表示当前调用对象。this是函数体内自带的一个对象指针,它能够始终指向调用对象。当函数被调用时,使用this可以访问调用对象。
为什么需要this
由于函数可以在不同的运行环境执行,所以需要有一种机制,能够在函数体内部获得当前的运行环境(context)。所以,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。
var a = 66 //被函数fn访问
var obj = {
a: 1,
fn: function () {
console.log(a) //打印66
}
}
obj.fn()
var obj2 = {
a: 1, //被函数fm访问
fm: function () {
this.b=1
console.log(this.a) //打印1
}
}
obj2.fm() //同时给obj2添加成员b
小结
从上面代码知道,当运行obj.fn() 时,是访问不到obj成员a,打印了全局变量a。为了能够访问到obj2的a成员,JavaScript就为我们提供了this,使得this.a能够访问obj2的成员a,同时能够添加或更新成员。
绑定规则
- 默认绑定:非严格模式下this指向全局对象window, 严格模式下
this会绑定到undefined
"use strict";
var fn = function () {
return this
}
console.log(fn()) //undefined
- 隐式绑定:对象以成员的方式调用函数时, 如 obj.foo()的调用方式, foo内的this指向obj
var obj = {
a: 1,
fn: function () {
return this
}
}
console.log(obj.fn()) //返回obj对象
- 显示绑定:apply,call,bind调用模式下,this指向第一个参数,如foo.call(obj)
var obj={
name:'蜗牛',
getName:function(){
console.log(this.name)
}
}
var otherObj={
name:'导弹'
}
var name='回想'
obj.getName()//蜗牛
obj.getName.call();//回想
obj.getName.call(otherObj);//导弹
obj.getName.apply();//回想
obj.getName.apply(otherObj);//导弹
obj.getName.bind(this)();//回想
obj.getName.bind(otherObj)();//导弹
- new绑定 :使用new来调用一个函数,会构造一个新对象并把这个新对象绑定到调用函数中的this。
function fn() {
this.a = 1
this.b = 2
}
var obj = new fn()
console.log(obj) //打印对象{a:1,b:2}
- 箭头函数绑定:this的指向由外层作用域决定的。
//声明位置
var fn = (()=>{
console.log(this.a)
})
var a=66
var obj={
a:1,
fn:fn
}
//调用位置
obj.fn();//66
//调用位置
fn();//66
根据函数的调用方式的不同,this 会指向不同的对象
- 以函数的形式(包括普通函数、定时器函数、立即执行函数)调用时,this 的指向永远都是 window。比如fun();相当于window.fun();
- 以方法的形式调用时,this 指向调用方法的那个对象
- 以构造函数的形式调用时,this 指向实例对象
- 以事件绑定函数的形式调用时,this 指向绑定事件的对象
- 使用 call 和 apply 调用时,this 指向指定的那个对象