严格模式

严格模式是什么

严格模式是 JavaScript 中的一种限制性更强的变种方式。严格模式不是一个子集: 它在语义上与正常代码有着明显的差异。

不支持严格模式的浏览器与支持严格模式的浏览器行为上也不一样,所以不要在未经严格模式特性测试情况下使用严格模式。

严格模式可以与非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。

严格模式的目的

首先,严格模式会将 JavaScript 陷阱直接变成明显的错误。

其次,严格模式修正了一些引擎难以优化的错误:同样的代码有些时候严格模式会比非严格模式下更快。

第三,严格模式禁用了一些有可能在未来版本中定义的语法。

开启严格模式

全局开启严格模式

需要在所有代码之前,定义一个不会赋值给任何变量的字符串;

 "use strict";	//或者'use strict'
开启严格模式 - 作用于全局作用域
// "use strict"
// 定义一个变量 - 不使用var关键字
a = 100;

console.log(a);
function fn(){
  // 开启严格模式 - 作用于函数作用域
  "use strict"
  v = 200;
  console.log(v);
}

fn();

函数开启严格模式

也可以为某个指定的函数开启严格模式,如下代码示例:

//函数外依旧是非严格模式
function doSomething(){
	"user strict";//开启严格模式
	//其他代码
}

在匿名函数中使用严格模式,相当于在全局开启严格模式的变通实现方式。

(function(){
	"use strict";//开启严格模式
})(); 

变量

禁止意外创建变量

在严格模式下,不允许意外创建全局变量。

  • 如下代码是非严格模式下意外创建全局变量。

    //未声明变量
    message = "this is message";
    
  • 如下代码是严格模式下意外创建全局变量。

    "use strict";//开启严格模式
    //严格模式下,意外创建全局变量,抛出ReferenceError
    message = "this is message"; 
    

案例:

// 开启严格模式
"use strict";

v = 100;
console.log(v);

function fn(){
    
    // 在非严格模式:在函数作用域中定义变量 - 不使用var关键字 -> 自动将其提升为全局变量
    w = 200;
    console.log(w);
}
fn();
console.log(w);

静默失败转为异常

所谓静默失败就是既不报错也没有任何效果,例如改变常量的值。在严格模式下,静默失败会转换成抛出异常。

  • 如下代码是非严格模式下的静默失败。

    const Pl = 3.14;
    Pl = 1.14; //静默失败
    console.log(Pl); //3.14
    
  • 如下代码是严格模式下的静默失败。

    "use strict"; //开启严格模式
    const Pl =3.14;
    Pl =1.14; //拋出IypeError错误
    

禁用 delete 关键字

在严格模式下,不能对变量使用 delete 运算符。

  • 如下代码是非严格模式下使用 delete 运算符,结果会静默失败。

    var color = "red";
    delete color; 
    
  • 如下代码是严格模式下使用 delete 运算符,结果会抛出异常。

    "use strict";//开启严格模式
    
    var color = "red";
    delete color;	//抛出ReferenceError错误
    

对变量名的限制

在严格模式下,JavaScript 对变量名也有限制。特别不能使用如下内容作为变量名:

implementsinterfacelet
packageprivateprotected
publicstaticyield

上述内容都是保留字,在ECMAScript的下一个版本中可能会用到它们。
在严格模式下,使用上述标示符作为变量名会导致语法错误。

对象

不可删除的属性

在严格模式下,不能使用 delete 运算符删除不可删除的属性。

  • 如下代码是非严格模式下使用 delete运算符删除不可删除的属性,结果会静默失败。

    delete Object.prototype;
    
  • 如下代码是严格模式下使用 delete 运算符符删除不可删除的属性,结果 会抛出异常。

    "use strict";//开启严格模式
    delete object.prototype; //拋出IypeError错误
    

属性名必须唯一

在严格模式下,一个对象内的所有属性名在对象内必须唯一。

  • 如下代码是非严格模式下重名属性是允许的,最后一个重 名的属性决定其属性值。

    var o = {p:1,p:2 };
    
  • 如下代码是严格模式下重名属性被认为是语法错误。

    "use strit";	// 开启严格模式
    varo={p:1,p:2 };	//!!语法错误
    

只读属性的赋值

在严格模式下,不能为一个只读的属性进行重新赋值。

  • 如下代码是非严格模式为只读属性重新赋值,结果会静默失败。

    var obj1 = {};
    
    Object.defineProperty(obj1, "x", { value: 42, writable: false });
    //将属性设置为只读
    
    obj1.x=9;
    
  • 如下代码是严格模式下为只读属性重新赋值,结果会抛出异常。

    "use strict";//开启严格模式
    
    varobj1={};
    Object.defineProperty(obj1, "x", { value: 42, writable: false });//将属性设置为只读
    
    obj1.x= 9; //抛出TypeError错误
    

不可扩展的对象

在严格模式下,不能为不不可扩展的对象添加新属性。

  • 非严格模式为不可扩展的对象添加新属性,结果会静默失败。

    var obj = {};
    Object.preventExtensions(obj);  //将对象变得不可扩展
    obj.newProp = 'ohai';
    
  • 严格模式不可扩展的对象添加新属性,结果会抛出异常

    "use strict";	//开启严格模式
    
    var obj = {};
    Object.preventExtensions(obj);	//将对象变得不可扩展
    obj.newProp = "ohai";	//抛出TypeError错误
    

函数

参数名必须唯一

严格模式下,命名函数的参数必须唯一

  • 非严格模式下最后一个重名参数名会掩盖之前的重名参数,之前的参数仍然可以通过arguments[i]来访问.

    function sum(a,a,c){}
    
  • 严格模式下重名参数被认为是语法错误

    function sum(a,a,c){	// !语法错误
    	"use strict"
    	
    	return a + a + c;	// 代码运行到这里会报错
    }
    

arguments 的不同

在严格模式下,arguments 对象的行为也有所不同。

  • 非严格模式下,修改密码参数的值也会有反应到arguments 对象中。
  • 严格模式下,命名参数与 arguments 对象是完全独立的。
//开启严格模式
"use strict";

function fn(value){
    var value = '二狗子';
    console.log(value); //二狗子 -> 就近原则

    /*
        *非严格模式下  -  arguments对象获取参数的值与形参有关的
            * 如果局部变量与形参名相同 - 根据就近原则进行获取
        *严格模式下   -  arguments对象获取参数的值与形参无关的
    
    */
   console.log(arguments[0]);   //二狗子
}
fn('大狗子');   //大狗子

arguments.callee()

在严格模式下,不能使用 arugments 对象的 callee() 方法。

  • 非严格模式下使用 arugments 对象的 callee()方法,表示调用函数本身。

    var f = function(){
    	return arguments.callee;
    } ;
    
  • 严格模式下使用 arugments 对象的 callee() 方法,结果会抛出异常。

    "use strict";	//开启严格模式
    
    var f = function(){
    	return arguments.callee;
    };
    f();	//抛出TypeError错误
    

函数声明的限制

在严格模式下,只能在全局域和函数域中声明函数。

  • 非严格模式下在任何位置声明函数都是合法的。

    if (ture){
    	function f(){}
    }
    
  • 严格模式下在除全局域和函数域中声明函数是语法错误。

    "use strict";	//开启严格模式
    
    if (true){
    	function f()  {}	//语法错误
    }
    

eval()函数

增加eval()作用域

在严格模式下,使用 eval() 函数创建的变量只能在eval()函数内部使用。

  • 非严格模式下 eval() 函数创建的变量在其他位置可以使用

    eval("var x = 42");
    console.log(x);	//42
    
  • 严格模式下 eval() 函数创建的变量只能在eval()函数内部使用。

    "use strict";       //开启严格模式
    
    eval("var x = 42");
    console.log(x);	//抛出ReferenceError错误
    

argument 对象

禁止读写

严格模式下,禁止使用 eval()arguments 作为标识符,也不允许读写他们的值。

  • 使用 var 声明
  • 赋予另一个值
  • 尝试修该包含的值
  • 用作函数名
  • 用作命名的函数的参数
  • try...catch 语句中用作例外名

严格模式下,导致语法错误的:

"use strict";       //开启严格模式

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

this关键字

抑制 this

  • 非严格模式下使用函数的 apply()call()方法时, nullundefined 值会被转换为全局对象。
  • 严格模式下,函数的this值始终是指定的值(无论什么值)。
var color = 'red';

function sayColor(){
	console.log(this.color);	//非严格模式下red
}							//严格模式下 抛出错误

sayColor.call(null);
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页