Strict Mode和Extended Mode - Javascript语法基本 - Javascript中心

原文: http://pij.robinqu.me/JavaScript_Core/JavaScript_Basics/Strict_Mode.html

源代码: https://github.com/RobinQu/Programing-In-Javascript/blob/master/chapters/JavaScript_Core/JavaScript_Basics/Strict_Mode.md

  • 本文须要补充更多例子
  • 本文存在讲明,但该网站的Markdown编辑器不支撑,所以没法一般展现,请到原文参考。

Strict Mode和Extended Mode

本文上一个版本盗用了他人的文章,经读者指出后我就删掉了。因为草拟的时候在客岁,我也不太清晰当初是怎样把他人的文章复制进来的。本文除了引见所谓的Strict Mode以外,还会引见其他关联内容。

JavaScript并非一个圆满的言语。事实上,第一个版本的Brendan Eich1消费十天的时候制造的,你不能对它希冀太多。以后,JavaScript在浏览器大战中,成为各方比赛的重要疆场。各大厂商各显神通,其副作用是种种奇奇怪怪的行动和各式不一的API。在以后,W3C和其他社区整体消费了大批的精神来经由过程规范化来“净化”一切Web开辟相干的手艺规范。

但为难的是,浏览器厂商并非那末完整的完成了W3C和ECMAScript的种种规范。末了,经验丰富的Javascript程序员,经由过程束缚自身对Javascript的运用方法,来到达让Javascript更高的可拥度。能够大部份人都读过《JavaScript言语精炼》2这本书,其报告的就是如安在JavaScript言语中,取其精华,然后去其糟粕。

而JavaScript的严厉形式,则是另一种紧箍咒,它的束缚力来自运转时自身,而不是用户的主观行动。也就是说,有许多含糊其词,或是毛病却被许可的操纵,被完全制止了。现在支撑严厉形式的支撑局限3从IE10起跳,其他常青浏览器也都是支撑的。

怎样开启

开启全局形式只需在一切语句之前安排"use strict"字符串常量。

全局开启严厉形式:

"use strict"
var v = "Hello world";

但注重,如许会致使全部剧本内的代码都在严厉形式中实行。如果之前有些代码并没有斟酌严厉形式,这能够让你的全部应用程序倏忽失效。

我们更加引荐的是,在某个函数内开启严厉形式:

function mySuperMethod() {
    "use strict";
    var v = "Hello world";
}

function mySuckingMethod {
    //not in strict mode
}

严厉形式的详细行动

人人有须要记着一堆言语特征了。然则,还好这些内容是把“歪”的掰“直”了。有少数代码例子来自于MDC4

抛出ReferenceError

  1. 试图隐式建立全局变量

    ```
    "use strict"
    hello = "world"//throw
    ```
    

抛出TypeError

  1. 试图修正已被定义为不可写的属性

    ```
    "use strict";
    var o = {};
    Object.defineProperty(o, "hello", {value:"world", wrtiable:false});
    o.hello = "bad boy";//throw
    ```
    

    其他相似的另有:

    • 给只读属性赋值
    • 给不可扩大的对象新建属性
  2. 试图删除不可删除的属性

    ```
    "use strict";
    delete Object.prototype; //throw
    ```
    
  3. arguments.callee不能被返回、删除、修正;

    ```
    "use strict";
    var fun = function() { 
        return arugments.callee;//throw
    };
    ```
    

抛出SyntaxError

  1. 反复定义属性名

    ```
    "use strict";
    var o = {hello: 1, hello: 2};//throw
    ```
    
  2. 禁用八进制字面量

    ```
    "use strict";
    var hello = 015;//throw
    ```
    
  3. 不许可反复参数名

    ```
    function myMethod(a, b, b) {//throw
        "use strict";
    }
    ```
    
  4. 不能运用with

    ```
    "use strict";
    var obj = {};
    with (obj) {};//throw
    ```
    
  5. 不许可对evalarguments赋值

    ```
    var fun = function(){
        "use strict";
        eval=16
    }();
    ```
    
  6. 不可将evalarguments作为参数名、变量名

    ```
    var fun = function(){
        "use strict"; 
        var obj = { 
            set p(arguments) {} 
        };
    }();
    ```
    

eval被限定在暂时的当地作用域

eval不再有权限直接修正其地点作用于,而只能影响自身建立的作用域。

var hello = "world";
var evalHello = eval("'use strict'; var hello = "girl"; hello");
// hello === "world"
// evalHello === "girl"

arguments不再追踪现实参数值变化

function f(hello)
{
  "use strict";
  hello = "girl";
  return [hello, arguments[0]];
}
var pair = f("world");
// pair[0] === "girl"
// pair[1] === "world";

函数的动态绑定后的this不做任何修正

  • 纵然指定nullundefined,引擎也不会从新指定全局对象作为this
  • 指定基本数据类型时,也不会用包装类举行转换
"use strict";
function fun() { return this; }
// fun() === undefined
// fun.call(2) === 2
// fun.apply(null) === null
// fun.call(undefined) === undefined
// fun.bind(true)() === true

挪用客栈不可被追踪

以往,我们能够经由过程函数的callerarguments来投影全部挪用客栈。然则,在严厉形式中我们做不到。

function restricted()
{
  "use strict";
  restricted.caller;    // throws a TypeError
  restricted.arguments; // throws a TypeError
}

ECMAScript6的相干特征

更多保留字

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

仅许可在开首运用function语句

许多开辟者喜好以下代码作风,这在严厉形式中会报错。

function foo()
{
  "use strict";
  return g;
  function g() { }//throw SyntaxError
}

这个转变的原因是,JavaScript的Hoisting特征会让许多人疑惑:

function g() { }
function foo()
{
    if (true)
    function g() { }
    return g;
}

Extended Mode

ES6 Draft中引入了一个新的观点5,叫Extend Mode,然后又被撤销了6。但不幸的是,V8中已支撑了这个新形式。所以,作为事实规范,现在依靠V8的一切Javascript运转环境都有以下三个形式:

  • Classic Mode,或许Non-strict mode
  • Strict Mode
  • Extended Mode

这个形式是备受争议的。这个形式的发生,也体会出制造一个规范的难题的地方——你总要斟酌新规范对老规范的兼容,尤其是Web手艺。

有轻微相识ES6的同砚都应该清晰,moduleclass这些东西已完整推翻了传统JavaScript的许多尝试。但也有不少东西,开辟者是能够接收,并立马去尝试的。于是乎,关于怎样让代码部份进入extended mode也就成了最初议论的重点7

现实表现上,node的0.11.x的版本,有些特征,仅仅运用--harmony并不能完整运用,还需加上--use_strict。在这里,已能够看出V8团队有多纠结了8。他们也没有想清晰,该怎样进入extended mode,干脆,也叫strict吧。

现在仅在extended mode下可用的ES6特征:

  • let
  • blockl-level function declaration

关于ES6的特征,请参考本书的相干章节。

  1. http://en.wikipedia.org/wiki/Brendan_Eich 

  2. http://book.douban.com/subject/3590768/ 

  3. http://caniuse.com/#feat=use-strict 

  4. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Strict_mode 

  5. http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts 

  6. http://wiki.ecmascript.org/lib/exe/fetch.php?id=harmony%3Aspecification_drafts&cache=cache&media=harmony:working_draft_ecma-262_edition_6_11-7-11.pdf 

  7. https://lists.webkit.org/pipermail/webkit-dev/2011-December/018903.html 

  8. https://code.google.com/p/v8/source/detail?r=10062 

    原文作者:RobinQu
    原文地址: https://segmentfault.com/a/1190000000517498
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞