严格模式下this的指向

880 阅读2分钟

严格模式是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