JS 必須知道的基礎《嚴格模式 'use strict'》

Image

Image by Pankaj Patelhtml

JS中的嚴格模式 'use strict'安全

JS的嚴格模式'use strict'應該是你們熟悉不過的知識,按字面意思來解釋就是遵循嚴格的行爲模式來寫代碼。但有那些規則來約束咱們在開發過程當中來使用嚴格模式規範本身代碼呢?因此這篇文章的目的僅僅是爲了再次加深對嚴格模式的認識。雖然本文是基礎知識,但但願對你們有所幫助。框架

嚴格模式的定義

use strict 是一種 ECMAscript5 添加的(嚴格)運行模式,這種模式使得 Javascript 在更嚴格的條件下運行。嚴格模式的實現使您的程序或函數遵循嚴格的操做環境。函數

設立"嚴格模式"的目的,主要有如下幾個:工具

  • 消除Javascript語法的一些不合理、不嚴謹之處,減小一些怪異行爲;
  • 消除代碼運行的一些不安全之處,保證代碼運行的安全;
  • 提升編譯器效率,增長運行速度;
  • 爲將來新版本的Javascript作好鋪墊。

嚴格模式的使用

爲腳本開啓嚴格模式

爲整個腳本文件開啓嚴格模式,須要在全部語句以前放一個特定語句 "use strict"; (或 'use strict';)優化

// 整個腳本都開啓嚴格模式的語法
"use strict";
var v = "Hi! I'm a strict mode script!";
複製代碼

這種語法存在陷進,要是合併一個嚴格模式的腳本和一個非嚴格模式的腳本:合併後看起來是嚴格模式。 反之亦然:非嚴格合併嚴格看起來是非嚴格的。因此建議要麼均開啓嚴格模式,要麼就不使用非嚴格模式。ui

爲函數開啓嚴格模式

給某個函數開啓嚴格模式,得把 "use strict"; (或 'use strict';)聲明一字不漏地放在函數體全部語句以前。this

function strict() {
  // 函數級別嚴格模式語法
 'use strict';
  function nested() { 
    return "And so am I!"; 
  }
  return "Hi! I'm a strict mode function! " + nested();
}

function notStrict() { 
  return "I'm not strict."; 
}
複製代碼

嚴格模式的規範

變量

嚴格模式下,使用變量的規則spa

  1. 不容許意外建立全局變量
  2. 不能使用 delete 操做符刪除聲明變量
  3. 不用使用保留字(例如 :implements、interface、let、package、 private、protected、public、static 和 yield 標識符)做爲變量名

規則1prototype

// 建立一個全局變量叫作message
message = "Hello JavaScript! "; // 這一行代碼就會拋出 ReferenceError
複製代碼

規則2

var x;
delete x; // !!! 語法錯誤

eval("var y; delete y;"); // !!! 語法錯誤
複製代碼

規則3

var private = 123; // !!! 語法錯誤
var public = 'hello'; // !!! 語法錯誤
複製代碼

對象

嚴格模式下,使用對象的規則

  1. 爲只讀屬性賦值會拋出TypeError
  2. 對不可配置的(nonconfigurable)的屬性使用 delete 操做符會拋出TypeError
  3. 爲不可擴展的(nonextensible)的對象添加屬性會拋出TypeError
  4. 使用對象字面量時, 屬性名必須惟一

規則1

// 給只讀屬性賦值
var obj2 = { get x() { return 17; } };
obj2.x = 5; // 拋出TypeError錯誤

// 給不可寫屬性賦值
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // 拋出TypeError錯誤
複製代碼

規則2

delete Object.prototype; // 拋出TypeError錯誤
複製代碼

規則3

// 給不可擴展對象的新屬性賦值
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // 拋出TypeError錯誤
複製代碼

規則4

var o = { p: 1, p: 2 }; // !!! 語法錯誤
複製代碼

函數

嚴格模式下,使用函數的規則

  1. 要求命名函數的參數必須惟一
function sum(a, a, c) { // !!! 語法錯誤
  return a + a + c; // 代碼運行到這裏會出錯
}
複製代碼

eval與arguments

嚴格模式下,使用eval與arguments的規則

  1. eval不在爲上下文中建立變量或函數
  2. eval 和 arguments 不能經過程序語法被綁定(be bound)或賦值
  3. 參數的值不會隨 arguments 對象的值的改變而變化
  4. 禁止使用arguments.callee
function doSomething(){
  eval("var x=10");
  alert(x); // 拋出TypeError錯誤
}
複製代碼

規則2 如下的全部嘗試將引發語法錯誤:

eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
var y = function eval() { };
var f = new Function("arguments", "'use strict'; return 17;");
複製代碼

規則3

function f(a) {
  a = 42;
  return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
複製代碼

規則4

var f = function() { 
  return arguments.callee; 
};
f(); // 拋出類型錯誤
複製代碼

禁止在函數內部遍歷調用棧

function restricted() {
  restricted.caller;    // 拋出類型錯誤
  restricted.arguments; // 拋出類型錯誤
}
複製代碼

靜態綁定

  1. 禁止使用with語句
  2. eval()聲明變量和函數只能當前eval內部的做用域中有效

規則1

var x = 17;
with (obj) { // !!! 語法錯誤
  // 若是沒有開啓嚴格模式,with中的這個x會指向with上面的那個x,仍是obj.x?
  // 若是不運行代碼,咱們沒法知道,所以,這種代碼讓引擎沒法進行優化,速度也就會變慢。
  x;
}
複製代碼

規則2

var result = eval("var x=10, y=11; x+y");
alert(result); //21
複製代碼

this指向

  1. 全局做用域的函數中的this再也不指向全局而是undefined。
  2. 若是使用構造函數時,若是忘了加new,this再也不指向全局對象,而是undefined報錯
// 規則1
function bar() {
  console.log(this)
}
bar() // undefined


// 規則2
function Person() {
  this.name = "Vincent" // Uncaught TypeError: Cannot set property 'name' of undefined
}

Person() // 報錯,使用構造函數時,若是忘了加new,this再也不指向全局對象,而是undefined.name。
複製代碼

總結

如今不少人在埋頭使用各類框架和工具,其實在咱們實際開發中是沒有問題的,由於帶來的是效率的提高。但萬物生長都離不開根, 因此基礎永遠都是基本核心的。我也知道每一個人的時間有限,並不能兼顧不少。但我仍是建議花點時間在基礎上,哪怕天天用10~20分鐘的時間再看看基礎知識,由於每次看完都會有必定收穫。

我本人技術功底不太好,基礎也不紮實,因此我天天提醒本身不要中止前進的腳步。

參考文獻

相關文章
相關標籤/搜索