this是js中的关键字,始终指向一个对象,this是一个指针
1.this的显示绑定和隐式绑定
显示绑定:
函数没有明确的调用对象的时候,将对函数的this使用默认绑定:绑定到window全局对象(函数fire一直居住在window里面)
- 1.1全局函数
function fire(){
console.log(this = window) //# fire是全局方法,this指向window
}
fire() //true
- 1.2函数内嵌套函数
function fire(){
function innerFire(){
console.log(this) //# 未明确调用对象,this指向window
}
innerFire() //# 独立函数调用
}
fire()
示例
var a = 1
console.log(a) // 1 全局变量a
console.log(this.a) // this指向window
function fire(){
var a = 2;
console.log(a) // 2 函数fire作用域a
console.log(this.a) // this指向window
function innerFire(){
var a = 3;
console.log(a) // 3 函数innerFire作用域a,从自身作用域找,未找到则往上找
console.log(this.a) // this指向window
}
innerFire()
}
fire()
1.3 对象的属性值的内部函数
var obj = {
fire:function(){
function innerFire(){
console.log(this) //未明确调用对象,此时this指向window
}
innerFire()
}
}
obj.fire()
示例
var a = 1;
console.log(this.a); //this指向window
var obj = {
a:2,
fire:function(){
var a = 3;
console.log(this.a) // obj.fire(),obj执行了函数fire,所以this指向obj
function innerFire(){
var a = 4;
console.log(this.a) // 未明确调用对象,this指向window
}
innerFire()
}
}
obj.fire()
隐式绑定:
1.1 当一个函数被一个对象包含的时候,this就被隐式绑定到这个对象上了,这时候可以通过this访问对象里的其他属性。
在隐式绑定下:函数只是暂时住在包含对象的旅馆里,过几天可能又要搬家了。
var obj = {
a:'111',
fire:function(){
console.log(this.a) //111,this指向obj
}
}
obj.fire()
或者这样写
var fire = function(){
console.log(this.a)
}
var obj = {
a:111,
fire:fire
}
obj.fire()
- 1.2 动态绑定:将函数赋值给全局变量(this从宾馆搬回家了)
var obj = {
a:1,
fire:function(){
console.log(this.a)
}
}
var a = 2 //全局的变量a
obj.fire() // 1, obj执行了函数fire,所以this指向obj,
var fireInGlobal = obj.fire; //因为fireInGlobal是全局变量,this从宾馆搬回家了
fireInGlobal() //this指向window,输出2
var a = 2;
var obj = {
a:3,
fire:function(){
console.log(this.a)
}
}
obj.fire() //3
function otherFire(fn){ //# otherFire是全局函数,this指向window
fn()
}
otherFire(obj.fire) //2,
2.this的指向问题
2.1 全局环境作用域:this在全局环境始终指向window
2.2 函数环境作用域:函数由谁调用,this就指向谁
2.2.1 非严格模式环境下
function fn(){
console.log(this) //window
}
fn()
console.log(fn === window.fn) //true
console.log(this === window) //true
console.log(fn === this.fn) //true
2.2.2 严格模式环境下
a 全局环境下,this指向window
b 函数环境下,this指向undefined
2.3 对象中的方法函数调用:this指向该方法所属的对象
同隐式绑定
2.4 构造函数中this始终指向新对象
2.5 通过事件绑定的方法: this 指向 绑定事件的对象
<button id="btn">点我</button>
oBtn.onclick = function(){
console.log(this) //btn
}
2.6 自执行函数(匿名函数): 指向全局变量window
2.7 箭头函数:
- 要点:
a. 箭头函数的this是在定义函数时绑定的, 不是在执行过程中绑定的
b. 箭头函数中的this始终指向父级对象
c. 所有 call() / apply() / bind() 方法对于箭头函数来说只是传入参数, 对它的 this 毫无影响。
3.更改this指向
1.call()
var person = {
name:'zf',
age:18
}
function lzf(x,y){
console.log(x,y)
console.log(this)
console.log(this.name)
}
lzf(1,2); //this指向window---1,2---window---null
lzf.call(person,1,2) //this指向person---1,2---person---zf
2.apply()用法同call(),只是apply的第二个参数是数组,数组里面是函数的参数
lzf.apply(person.[1,2])
3.bind(),有点不一样,他并不是改变this的指向,而是创建一个新的函数体。
var Person = {
name: "zf",
age: 19
}
function lzf(x, y) {
console.log(x + "," + y);
console.log(this);
console.log(this.name);
}
lzf.bind(Person, 4, 5); //只是更改了this指向,没有输出
lzf.bind(Person, 4, 5)(); //this指向Person-- 4,5 Person{}对象 zf
4.存储this指向到变量中
var oDiv1 = document.getElementById("div1");
oDiv1.onclick = function () {
var _this = this; //将this储存在变量中,而且不改变定时器的指向
setTimeout(function () {
console.log(_this); //注意这里是_this,而不是this-- <div id="div1">点击</div>
console.log(this); //定时器的指向没有被改变--仍然是window
}, 1000)
}