您的位置:首页 > Web前端 > JavaScript

javascript中的严格模式

2016-05-18 15:34 447 查看
ECMAScript5的strict mode在javascript中是一种限制变量的一种方式。strict mode 不仅仅是一个子集:它的本意就是从正常的代码中有不同的语意。不支持严格模式的浏览器运行严格模式下的代码将有不同的行为,所以不要依靠没有功能测试支持相关方面的严格模式.

另外,严格模式和非严格模式的代码可以共存,所以脚本可以选择严格模式。

严格模式较正常的JavaScript语义有几项变动:

首先,严格模式通过抛出错误消除了一些JavaScript静态的错误。

其次,严格模式修复了javascript引擎优化实现困难的问题,严格模式经常使得代码运行的比非严格模 式下的代码更快。

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

Invoking strict mode

严格模式使用于整个script或者私有方法,并不作用于用{}围起来的代码片段(非function)尝试应用于这样的环境并没有eval代码,功能函数,事件处理程序的属性,字符串传入setTimeout等整个脚步加载完成,并调用严格模式按照预期运行。

Strict mode for scripts

让整个script使用严格模式,就需要把语句”use strict”放在所以声明的前面,

// Whole-script strict mode syntax

“use strict”;

var v = “Hi! I’m a strict mode script!”;

Strict mode for functions

同样的,为一个function启用严格模式也是将语句”use strict”放在所以声明的前面,

同样的,为一个function启用严格模式也是将语句”use strict”放在所以声明的前面,

function strict(){

// Function-level strict mode syntax

‘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.”;

}

Changes in strict mode

严格模式改变了语法和运行时行为,改变的设计如下几个方面:改转换异常为错误,简化特定变量,简化了eval和arguments。这些改变可以让你的javascript代码更加安全,也预示着ECMAScript未来的变化。

下面一一介绍变化的方面:

Converting mistakes into errors

严格模式让提前可以接受的错误变成脚步无法运行的错误。对javascript初学者来说变得容易得多了,并且有时候给出的操作为错误而非语意错误。我们经常修复中级别的错误,但是还会给未来造成更严重的错误。严格模式视这些错误为error级别的提示开发者可以发现并且及时修复。

首先,严格模式可以让你不会意外地声明一个全局变量。在原生的javascript中定义变量不完整就可以让这个变量暴露在了全局中并且还能运行。这时你就可以把代码撇到严格模式中。

“use strict”;

mistypedVaraible = 17; // this line throws a ReferenceError due to the mispelling of variable

第二,严格模式使得内存分配默默地消失抛出一个异常。例如,NaN是个全局的不可写的变量,通常我们不能给NaN设置值,开发者不会得到错误反馈。在严格模式中给NaN设置值会抛出一个异常。在原生js中任何给不可写的元素赋值,给只有get方法的元素赋值和给不可扩展的属性赋值都是隐含的错误,这样还是放在严格模式里面比较好。如下:

“use strict”;

// Assignment to a non-writable property

var obj1 = {};

Object.defineProperty(obj1, “x”, { value: 42, writable: false });

obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property

var obj2 = { get x() { return 17; } };

obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object

var fixed = {};

Object.preventExtensions(fixed);

fixed.newProp = “ohai”; // throws a TypeError

第三,严格模式使得试图删除对象内置的属性时依然会报typeerror。如下:

"use strict";
delete Object.prototype; // throws a TypeError


第四,严格模式要求声明到对象中属性是唯一的。在原生的js中对象中的属性是可以重复的,最后一个声明的属性值会覆盖在原来声明的属性值。如果只是改变对象的属性而不是改变改变最后一个实例的话,重复只是一种错误的实现,因为最后一个属性就能做任何事情。重复的属性在严格模式中会提示错误。

“use strict”;

var o = { p: 1, p: 2 }; // !!! syntax error

第五,严格模式要求function的参数名称是唯一的。在非严格模式下重复的参数会隐藏掉前面的参 数, 之前的仍然通过arguments[i]进行访问。

function sum(a, a, c){ // !!! syntax error

“use strict”;

return a + b + c; // wrong if this code ran

}

第六,严格模式禁止8进制数据(即015形式)(8进制不是ECMAScript规范的一部分)

“use strict”;

var sum = 015 + // !!! syntax error

197 +

142;

Simplifying variable uses

严格模式简化了变量名在代码中的定义,许多的编译器优化依赖变量所在的位置,这个对于javascript的系统优化是很关键的。首先,严格模式禁止with的使用(不推荐使用的不再相信介绍,只是描述下而已),因为with非常不利于优化。

“use strict”;

var x = 17;

with (obj) // !!! syntax error

{ x;}

并且严格模式下,传入eval的代码不能在调用程序所在的上下文定义属性和方法,在非严格模式下是可以这么做的。相反,变量和函数的定义是在eval创建新的作用域中这个作用域就不再使用了。

Making eval and arguments simpler

首先,eval和arguments都不能被绑定和赋值,下面所有的情况都是语法错误:

“use strict”;

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;”);

第二,严格模式下arguments不能起别名,在非严格模式下参数是arg的function,如果是给arg赋值,同样会修改arguments[0],反之亦然。在严格模式中,如果方法别调用,function会存储最原始的arguments对象,arguments[i]不在绑定对应的命名参数,请看下面的例子:

function f(a){

“use strict”;

a = 42;

return [a, arguments[0]];

}

var pair = f(17);

console.info(pair[0] === 42);

console.info(pair[1] === 17);

第三,arguments.callee不在支持

“use strict”;

var f = function() { return arguments.callee; };

f(); // throws a TypeError

“Securing” JavaScript

严格模式使得可以轻松地写安全的javascript代码,有些网站现在提供的方式是为用户编写JavaScript将通过在网站上代表其他用户运行,javascript可以访问到用户的一些隐私信息,所以很多的js代码 运行请做一定的转换,检查一些功能的可访问性,javascript的灵活性使得这种改变很简单。

首先,在严格模式下做为this的引用给函数传值的时候不再强制要求是个object,在非严格模式下的function中,this通常是一个对象:如果使用对象调用,this就被包装成对象,如果使用Boolean,string,nubmer 去调用this就会被包装成对应的值。不止自动包装会有性能损失,并且暴露到公共的环境中也是有风险的。安全的代码必须是有所限制的。对应一个严格模式下的function,就算是指定了this的值,也不会被包装。如果没有指定就会是undefined。

“use strict”;

function fun() { return this; }

console.info(fun() === undefined);

console.info(fun.call(2) === 2);

console.info(fun.apply(null) === null);

console.info(fun.call(undefined) === undefined);

console.info(fun.bind(true)() === true);

console.info

也就是说,在严格模式中,this不在指向了window对象,非严格模式下的this可以参考我的另一篇博文 /article/7221459.html

后面是不怎么常用的点,需要的可以看原文。

原文地址:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

参考资料:javascript权威指南第六版
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: