严格模式是ES5增加的新概念。严格模式是一种不同的JavaScript解析和执行模型,对于不安全的活动抛出错误。使用严格模式需要在代码开头加上:"use strict";也可以在函数体中单独使用,放在函数体开头:function fn(){"use strict";}
总结: 严格模式下,执行函数时没有执行主体,因此this指向undefined,非严格模式下的执行主体默认是window,因此this指向window。
1. 自执行函数的this
严格模式
- this为undefined
"use strict";
function fn(){
console.log(this)
}
fn() // undefined
非严格模式
- this为window
function fn(){
console.log(this)
}
fn() // window
注意:
- 箭头函数在严格模式和非严格模式下的this一致
- 严格模式或非严格模式下,使用call,apply,bind等结果一致
"use strict";
const fn = ()=>{
console.log(this)
}
fn() // window
let obj = {}
fn.call(obj) //window 严格模式与非严格模式一致
2. 事件绑定函数中的this
严格模式与非严格模式一致,非箭头函数指向当前操作的元素,箭头函数指向window
- 非箭头函数
// 严格模式
"use strict";
function fn(){
console.log(this)
}
const btn = document.getElementById('btn')
btn.addEventListener('click',fn)//<button id="btn">按钮</button>
// 非严格模式
const btn = document.getElementById('btn')
btn.addEventListener('click', function (){
console.log(this) // <button id="btn">按钮</button>
})
- 箭头函数
// 严格模式
"use strict";
const btn = document.getElementById('btn')
btn.addEventListener('click', ()=>{
console.log(this) // window
})
// 非严格模式
const btn = document.getElementById('btn')
btn.addEventListener('click', ()=>{
console.log(this) // window
})
3. 对象的方法
- 通过对象调用方法,严格模式与非严格模式的this指向一致
- 将方法赋值后直接调用,严格模式下是undefined,非严格模式是window
"use strict";
const obj = {
fn:function(){
console.log(this)
}
}
obj.fn() // obj
obj.fn.call(window) // window
const fn2 = obj.fn
fn2() // undefined,非严格模式下是window
4. 构造函数
严格模式
- 通过实例调用this指向实例,通过构造函数调用,this指向构造函数
- 先赋值后再调用,this指向undefined, 在非严格模式下是window
"use strict";
function Demo(){ }
Demo.prototype.callthis = function(){
console.log(this)
}
Demo.fn = function(){
console.log(this)
}
const d = new Demo()
d.callthis() // d
Demo.fn() // Demo
let fn = d.callthis
fn() // undefined 非严格模式下是window
5. 类中的方法默认开启了严格模式
- 由于callthis方法和fn方法是在类中定义的,该方法内部默认开启了严格模式,因此先赋值再调用时,其this指向了undefined
// 非严格模式
class Demo{
callthis(){
console.log(this)
}
static fn(){
console.log(this)
}
}
const d = new Demo()
// d.callthis() // d
// Demo.fn() // Demo
let fn = d.callthis
fn() // undefined
let fn2 = Demo.fn
fn2() // undefined