严格模式与非严格模式下的this

113 阅读2分钟

一、全局作用下的this

严格模式与非严格模式表现一致,this指向window对象。

"use strict"
console.log(this); // window对象

// 非严格模式
console.log(this); // window对象

二、全局作用域下,函数中的this

1.普通函数

严格模式下,普通函数中的this指向为undefined;非严格模式下,this指向window。

例1:

"use strict";
var text = "111";
function fn() {
  console.log(this.text);
}
fn(); // TypeError: Cannot read properties of undefined (reading 'text')

// 非严格模式下
var text = '111';
function fn(){
  console.log(this.text)
}
fn(); // 111

例2:

"use strict";
function f1() {
  function f2() {
    console.log(this);
  }
  f2();
}
function f3() {
  return function f4() {
    console.log(this);
  }
}
f1(); // undefined
f3()(); // undefined

// 非严格模式下
function f1() {
  function f2() {
    console.log(this);
  }
  f2();
}
function f3() {
  return function f4() {
    console.log(this);
  }
}
f1();    // window对象
f3()();  // window对象

2.箭头函数

严格模式与非严格模式表现一致。

"use strict";
const fn1 = () => {
  console.log(this);
};
const fn2 = () => {
  const fn3 = () => {
    console.log(this);
  };
  fn3();
};
const fn5 = () => {
  return () => {
    console.log(this);
  };
};
fn1();   // window对象
fn2();   // window对象
fn5()(); // window对象

3.普通函数与箭头函数相互嵌套

无论怎么嵌套,各自模式下的this指向相同。

"use strict";
const fn1 = function () {
  const fn = () => {
    console.log(this);
  };
  fn();
};
function fn2() {
  const fn = () => {
    console.log(this);
  };
  fn();
}
const fn3 = () => {
  const fn = function () {
    console.log(this);
  };
  fn();
};
const fn4 = () => {
  function fn() {
    console.log(this);
  }
  fn();
};
fn1();   // undefined
fn2();   // undefined
fn3();   // undefined
fn4();   // undefined

// 非严格模式下
fn1();   // window对象
fn2();   // window对象
fn3();   // window对象
fn4();   // window对象

4.对象中的函数

严格模式与非严格模式表现一致。对象的函数中的this,指向调用函数的对象实例(箭头函数指向定义时的上层作用域)。

例1:

"use strict";
var text = "window";
let obj = {
  text: "obj",
  fn1() {
    console.log(this.text);
  },
  fn2: function () {
    console.log(this.text);
  },
  fn3: () => {
    console.log(this.text);
  },
  obj1: {
    text: 'obj1',
    fn4() {
      console.log(this.text);
    },
    fn5: () => {
      console.log(this.text);
    },
  },
};
obj.fn1(); // obj
obj.fn2(); // obj
obj.fn3(); // window
obj.obj1.fn4(); // obj1
obj.obj1.fn5(); // window

对象属性上的箭头函数表现与普通函数不一致的原因:对象不构成单独的作用域,导致箭头函数定义时的作用域就是全局作用域。

例2:

严格模式下报错,非严格模式下正常运行。

"use strict"
let greet = {
  text: "hello",
  sayHi: function () {
    console.log(this.text);
  },
  sayBye: function () {
    console.log('Bye');
  },
  set: na => {
    this.text = na;
  }
};
greet.set('world'); // 这里的this指向window对象

// 表示在全局环境下运行。
// sayHi为普通函数。严格模式下,this为undefined;非严格模式下,this为window对象。
// sayHi为箭头函数。在两种模式下表现一致,皆可正常运行。
(greet.text === 'hello' ? greet.sayHi : greet.sayBye)();
// TypeError: Cannot read properties of undefined (reading 'text')

// 非严格模式下
(greet.text === 'hello' ? greet.sayHi : greet.sayBye)();  // world

例3:

"use strict"
function test(name) {
  console.log(name);
  console.log(this);
}
test('Tom');  // Tom undefined
test.call(null, 'Tom');  // Tom null
test.call(undefined, 'Tom');  // Tom undefined

// 非严格模式下
function test(name) {
  console.log(name);
  console.log(this);
}
test('Tom');  // Tom window对象
test.call(null, 'Tom');  // Tom window对象
test.call(undefined, 'Tom');  // Tom window对象