1.一般函数中,严格模式下this为undefined,非严格模式下this为window。
var name = 'chen';
function nonStrictMode() {
console.log(this.name); //'chen'
}
function strictMode() {
'use strict'
console.log(this?.name); //undefined
}
nonStrictMode()
strictMode()
2.对象中函数的this,指向调用该函数的对象。
var name = "nick" //var全局作用域(挂载到window)
let obj = {
name: 'nancy', //局部作用域
sayName: () => {
console.log('name:', this.name); //nick
},
sayFucName: function() {
console.log('name:', this.name); //nancy
}
}
obj.sayName()
obj.sayFucName()
3.构造函数里的this,指向创建出来的实例。
function People(name, age) {
this.name = name
this.age = age
this.introduce = function(){
console.log(`我叫${this.name} 今年${this.age}岁`);
}
}
let child = new People("小明", 18)
child.introduce() //我叫小明 今年18岁
4.事件处理函数中,指向触发该事件的元素。
5.箭头函数没有自己的this,它的this指向定义它时所处的环境。(首先查找父级作用域中的this,如父级作用域还是箭头函数,则继续向上查找,直到找到this指向)
var name = 'nick';
var obj = {
name: 'nancy',
sayName: () => {
return () => {
console.log('name:', this.name); //nick
}
}
}
var fun = obj.sayName()
fun() //最后fun是由window调用的,所以name为nick
改变this指向
function fn(x, y) {
console.log('指向:',this);
console.log(x + y);
}
let obj={
name:'nick',
hobby:'basketball'
}
//第一个参数改变了this的指向,其他参数对应函数里的参数,立即执行=>call
fn.call(obj,5,7)
//第一个参数改变了this的指向,第二个参数是个数组,立即执行=>apply
fn.apply(obj,[5,7])
//第一个参数改变了this的指向,其他参数对应函数里的参数, //但需调用再执行=>bind
let emit = fn.bind(obj,5,7)
emit()
JS中setTimeout函数对改变this指向的影响
1.一般函数中居然没有改变this指向!
let obj = {
name: 'latency'
}
var name = 'cheng';
function fun() {
setTimeout(function () {
console.log('name:', this.name);
}, 100)
}
fun.call(obj) //name: cheng
问题原因
从上述例子中可以看到setTimeout中函数内的this是指向了window对象,这是由于setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window ,从而改变this指向没有作用。
2.箭头函数中的this指向改变
var name = 'cheng';
function arrowFun() {
setTimeout(() => {
console.log('name:', this.name);
}, 100)
}
arrowFun.call(obj) //name: latency
ES6中的箭头函数完全修复了this的指向,改变this指向时,指向传入的对象。