this
函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系
大部分情况下this如一个参数,指向所在函数的调用者
1.全局作用域或者普通函数中this指向全局对象window(定时器里面的this也指向window)
function fn(){
console.log(this) //==>指向全局window
}
setInterval(function(){
console.log(this) //==>指向全局window
},1000}
2.方法调用中谁调用this指向谁(即对象中的方法的this指向对象)
var obj={
fn:function(){
console.log(this); //==>指向对象obj
}
}
obj.fun()
3.事件驱动调用this指向绑定事件源
element.addEventListener('click',function(){
console.log(this); //==>指向事件源element
})
4.构造函数中的this指向构造函数的实例
function CreatObj(){
this.fn=function(){
console.log(this); //==>当使用构造函数创建对象,this指向构造函数的实例obj
}
console.log(this); //==>构造函数本质是函数 this指向全局window
}
var obj=new CreatObj;
CreatObj()
obj.fn()
5.原型对象函数里面的this指向实例对象
function CreatObj(){
}
var obj=new CreatObj;
CreatObj.prototype.fn=function(){
console.log(this) //==>原型对象函数里面的this指向实例对象
}
CreatObj()
obj.fn()
6.立即执行函数
(function () {
console.log(this) //==>指向全局window
})()
严格模式下this指向
1.全局作用域函数中函数的this是undefined
2.构造函数中不加new调用,this会报错
3.定时器this还是指向window
4.事件、对象还是指向调用者
改变this指向
call 和 apply 和 bind
强行改变 this 指向的方法
call
call
方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向
语法: 函数名.call(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...)
var obj = { name: 'Jack' }
function fn(a, b) {
console.log(this)
console.log(a)
console.log(b)
}
fn(1, 2)
fn.call(obj, 1, 2)
fn()
的时候,函数内部的 this 指向 window
fn.call(obj, 1, 2)
的时候,函数内部的 this 就指向了 obj 这个对象
不需要改变this指向时可以fn.call(null, 1, 2)
使用 call 方法的时候会立即执行函数
第一个参数是你要改变的函数内部的 this 指向
第二个参数开始,依次是向函数传递参数
eg:
//使用call改变this指向让本来数据的原型没有这个方法 也可以使用此方法
Object.prototype.toString.call() //检测数据类型(本质上输出调用的数据类型的构造函数)
Array.prototype.slice.call() //伪数组转换为数组(本质上用slice返回值为一个数组)
//因为Object.prototype也是在对象的原型中找方法 所以可以简写为
{}.toString.call()
[].slice.call()
apply
apply
方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向
语法: 函数名.apply(要改变的 this 指向,[要给函数传递的参数1, 要给函数传递的参数2, ...])
var obj = { name: 'Jack' }
function fn(a, b) {
console.log(this)
console.log(a)
console.log(b)
}
fn(1, 2)
fn.call(obj, [1, 2])
fn()
的时候,函数内部的 this 指向 window
fn.apply(obj, [1, 2])
的时候,函数内部的 this 就指向了 obj 这个对象
使用 apply 方法的时候会立即执行函数
第一个参数是你要改变的函数内部的 this 指向
第二个参数是一个 数组,数组里面的每一项依次是向函数传递的参数
bind
bind
方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向
和 call / apply 有一些不一样,就是不会立即执行函数,而是返回一个已经改变了 this 指向的函数
语法: var newFn = 函数名.bind(要改变的 this 指向); newFn(传递参数)
var obj = { name: 'Jack' }
function fn(a, b) {
console.log(this)
console.log(a)
console.log(b)
}
fn(1, 2)
var newFn = fn.bind(obj)
newFn(1, 2)
bind 调用的时候,不会执行 fn 这个函数,而是返回一个新的函数
这个新的函数就是一个改变了 this 指向以后的 fn 函数
fn(1, 2)
的时候 this 指向 window
newFn(1, 2)
的时候执行的是一个和 fn 一摸一样的函数,只不过里面的 this 指向改成了 obj
可用于定时器等不需要手动调用的函数
setInterval(function(){
//code
}.bind(this),1000)
//通过bind将this指向定时器外部作用域(此时this在定时器函数function外)
//效果跟箭头函数一样