js嚴格模式下的this指向,es6模組預設使用嚴格模式

KangTongShun發表於2020-12-12

一、問題描述

有這麼一段程式碼,他的執行結果是什麼呢?

class A {
	print() {
		console.log("==>", this);
	}
}

var aa = new A();
var print = aa.print;
aa.print();
print();

二、解題思路

我們一眼略過,迅速說出了答案

//A{}
//window{}

很遺憾,不對。答案是

//A{}
//undefined

這是為毛啊?肯定瀏覽器有毛病,那麼我們把這段程式碼用babel轉一下,轉成es5的形式,看看有什麼貓膩。

var A = /*#__PURE__*/function () {
  "use strict";

  function A() {}

  var _proto = A.prototype;

  _proto.print = function print() {
    console.log("==>", this);
  };

  return A;
}();

var aa = new A();
var print = aa.print;
aa.print();
print();

上面自動加了嚴格模式,後來查閱資料知道

ES6 的模組自動採用嚴格模式,不管你有沒有在模組頭部加上"use strict";。

類或者一個js檔案就是一個模組,所以會自動使用嚴格模式。
嚴格模式主要有以下限制。

  • 變數必須宣告後再使用;
  • 函式的引數不能有同名屬性,否則報錯;
  • 不能使用with語句;
  • 不能對只讀屬性賦值,否則報錯;
  • 不能使用字首0表示八進位制數,否則報錯;
  • 不能刪除不可刪除的屬性,否則報錯;
  • 不能刪除變數delete prop,會報錯,只能刪除屬性delete global[prop];
  • eval不會在它的外層作用域引入變數;
  • eval和arguments不能被重新賦值;
  • arguments不會自動反映函式引數的變化;
  • 不能使用arguments.callee;
  • 不能使用arguments.caller;
  • 禁止this指向全域性物件
  • 不能使用fn.caller和fn.arguments獲取函式呼叫的堆疊;
  • 增加了保留字(比如protected、static和interface)。

好,其他的我們日後再看,我們提取關鍵資訊 - 禁止this指向全域性物件
這是什麼意思呢?也就是當我們沒有指定函式的呼叫者時,函式不會預設指向全域性物件window
下面舉個例子

"use strict";
function f() {
	console.log(this);
}
f()//log:  undefined
window.f()//log:  window{}

三、總結
這題答錯的主要原因是因為,我不知道es6會預設使用嚴格模式。以及嚴格模式的一些特點,瞭解之後發現也沒有這麼燒腦,還是知識儲量太少,要多加練習哦。。

相關文章