zoukankan      html  css  js  c++  java
  • JavaScript严格模式

    • 初步了解严格模式
    • 一个用心良苦的语言模式设计

     一、初步了解严格模式

    ECMAScript 5的严格模式是采用具有限制性JavaScript变体的一种方式,从而使代码显示地“脱离马虎模式/稀松模式/懒散“模式。

    为什么这么说呢?有时候忘记在作用域链上是否存在某个变量了,或者忘记在那一层作用域,但是当前作用域需要对这个似乎存在的变量赋值,在非严格模式下可以直接在当前作用域给这个变量赋值,如果在作用域链上不存在这个变量,最终这个变量会被定义到全局。

    这种不严谨的代码在非严格模式下可能看起来不会有什么问题,但是对于全局变量命名会造成非常大的困扰,而且程序性能也会受到很大的挑战。

    往好的方向说非严格模式对这种错误行为的静默是一种容错行为,但是这必然会带来另一种情况就是:可能在编程中写错一个变量名的赋值行为,这时候程序不能正确修改变量的值,还错误的在全局添加了一个变量,若说这是一种容错行为,显然不是一个很好的编程思想。

    随着前端程序的复杂性越来越高,JavaScript这种不严谨的编码方式给代码的编写和管理带来了很大的挑战,在ES6的一些语法中就为了摒弃这种不严谨的行为出现了新的语法模式,语言设计者为了从ES5到ES6的过渡,以及为了JS语言能承担其未来的前端发展,在ES5中提出了严格模式。

    严格模式的具体内容:

    1.不允许使用为申明的变量:

    1 "use strict"
    2 a = 10; // 报错
    3 function fun(){
    4     b = {                //报错
    5         name:"他乡踏雪" 
    6     };
    7 }

    2.不允许删除变量:

    1 "use strict"
    2 var x = 3.14;
    3 function fun(){
    4     return 123;
    5 }
    6 delete x;         //报错
    7 delete fun;        //报错

    3.不允许变量重命名:

    1 "use strict"
    2 function fun(a, a){};//报错:准确说是不允许形参重命名
    3 function foo(a){
    4     var a = 10; //不报错
    5 }

    4.不允许八进制的数值:

    1 "use strict";
    2 var x = 010; //报错

    5.不允许转义字符:

    1 "use strict";
    2 var x = 10;  //报错

    6.不允许对只读属性赋值:

    1 "use strict";
    2 var obj = {};
    3 Object.defineProperty(obj, "x", {value:0, writable:false});
    4 obj.x = 3.14; //报错

    6.0这种也算是不允许只读属性赋值:

    1 "use strict";
    2 var obj = {get x() {return 0} };
    3 obj.x = 3.14;  //报错

    7.不允许删除不允许删除的属性:

    1 "use strict";
    2 delete Object.prototype; //报错,虽然这种删除在非严格模式下也没有实际意义

    8.不能使用with语句:(如果需要了解with的实现原理:https://www.cnblogs.com/ZheOneAndOnly/p/11333635.html)

    1 "use strict";
    2 with (Math){x = cos(2)}; //报错:因为严格模式不能使用未定义变量直接赋值

    9.严格模式下全局eval()会创建自己的作用域(意味着在严格模式下全局eval语句没有实际意义):

    1 "use strict"
    2 eval("var a = 10");
    3 console.log(a); //a is not defined

    10.不能使用arguments作为变量名,作为一个非关键字,在严格模式下也不能使用其作为变量名:

    1 "use strict";
    2 var arguments = 3.14; //报错

    11.禁止this指向全局对象:

    1 "use strict"
    2 function fun(){
    3     console.log(this); //undefined ,可以说直接执行函数没有this指向(未定义),不能说他指向undefined
    4 }
    5 fun();

    11.0所以如果在严格模式下方法内使用this就必须是被对象调用执行,未定义的this返回undefined,undefined不能有属性和方法。所以如果在严格模式下使用方法来构建对象忘了写new关键字,构造方法内使用this来定义对象属性和方法就必然会报错,而不再是之前的函数执行时this指向window全局对象。

    1 function f(){
    2     "use strict";
    3     this.a = 1;
    4 };
    5 f();// 报错,this未定义

    12.严格模式下原始值类型不会发生隐式类型转换:

    1 "use strict"
    2 var a = 10;
    3 a.text = "10"; //报错

    13.严格模式新增关键字:

    implements、interface、let、package、private、protected、public、static、yield

    声明严格模式:

    1 "use strict" //全局声明严格模式:在全局的顶端声明,前面可以出现注释。
    2 
    3 function fun(){
    4     "use strict" //函数内部声明严格模式:在函数的作用域内的第一行声明,同样前面只可以出现注释5 }

     严格模式的兼容性:

    IE 10、Firefox 4、Chrome 13、 Safari、Opera 12。

    在不支持严格模式的浏览器也不用担心,根据严格模式编写的代码相比非严格模式的代码具备更好的可靠性,非严格模式的声明只是一个字符串赋值空执行。

     二、一个用心良苦的语言模式设计

     2.1严格模式对正常的JavaScript做的一些更改:

    • 严格模式下通过抛出错误来消除原有静默的错误。
    • 严格模式修复了一些导致JavaScript引擎难以执行的缺陷:有时候相同的代码,严格模式可以比非严格模式运行得更快。
    • 严格模式禁用了在ECMAScript得未来版本中可能会定义得一些语法。

    2.2将过失错误转换成异常:

    • 严格模式下不会在意外情况下创建全局变量。(第一部分中情况1)
    • 严格模式下会使引起静默失败不报错抛出异常,比如NaN是不可写得全局变量,正常模式下给NaN赋值不会产生任何作用也不会反馈错误信息。(第一部分情况6)
    • 在严格模式下删除不可删除得属性时会抛出异常。(第一部分情况7)
    • 严格模式下对象属性不能重命名(ES6中已经修复,不抛出错误)
    • 严格模式下参数名唯一。(第一部分情况3)
    • 严格模式下ECMAScript中包含八进制语法。(第一部分情况4)
    • 严格模式下原始值(primitive)类型不会发生隐式类型转换。(第一部分情况12)

    2.3简化变量得使用:

    很多编译器得优化是依赖追踪变量位置得能力,但是在正常模式下有几种情况没法正确得追踪到变量得位置,比如with中的变量、eval中生成得变量都是动态生成得结构,没办法正确定位,这种情况下就没办法做代码优化。

    2.3.1在严格模式禁用了with,限定了eval在全局作用下创建独立作用域,这时候变量也不会影响到全局上变量了。(第一部分情况8,9)

    2.3.2严格模式下还禁止了删除变量。(第一部分情况7)

    2.3.3arguments不能作为变量名。(第一部分情况10)

    简化变量使用后,能让编译器更好的优化代码(具体内部原理还不清楚,只是在MDN手册上阅读到这些操作有利于编译器优化代码)。

    2.4安全的JavaScript

     1.4.1严格模式下this不会被强制转换成一个对象,原始值类型不会被隐式转换。

     1.4.2严格模式下不能删除函数的caller和arguments属性,并且读写都会报错。

     1.4.3严格模式下不能使用arguments访问和调用这个函数的相关变量。

    这些处理过后会让JavaScript变得更安全。

    更多相关内容可以访问MDN手册:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

  • 相关阅读:
    iOS——归档对象的创建,数据写入与读取
    iOS——plist的创建,数据写入与读取
    SQL SERVER 2005快捷键
    图片放大源码
    验证url 地址是否是图片
    JS三大经典变量命名法
    载入锁频
    SQL Server 查询分析器键盘快捷方式
    关于ajax get方式请求 url地址参数怎么变成空了的问题
    SQL计算表的列数
  • 原文地址:https://www.cnblogs.com/ZheOneAndOnly/p/11333636.html
Copyright © 2011-2022 走看看