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分钟的时间再看看基础知识,由于每次看完都会有必定收获。

我本人技术功底不太好,基础也不扎实,因此我天天提醒本身不要中止前进的脚步。

参考文献

相关文章
相关标签/搜索