54-附录-严格模式

一、严格模式

ECMAScript 5 最早引入了“严格模式”(strict mode)的概念。
通过严格模式,可以在函数内部选择进行较为严格的全局或局部的错误条件检测。
使用严格模式的好处是可以提早知道代码中存在的错误,及时捕获一些可能导致编程错误的 ECMAScript 行为。
支持严格模式的浏览器:IE10+、Firefox 4+、Safari 5.1+ 和 Chrome。

1. 选择使用

"use strict";
如果是在全局作用域中(函数外部)给出这个编译指示,则整个脚本都将使用严格模式。

只在函数中打开严格模式:

function doSomething(){
    "use strict";
    //其他代码
}
2. 变量

严格模式下,限制什么时候创建变量以及怎么创建变量。

  • 不允许意外创建全局变量
  • 不能对变量调用 delete 操作符
  • 对变量名也有限制(保留字)
//未声明变量 
//非严格模式:创建全局变量 
//严格模式:抛出 ReferenceError
message = "Hello world! ";

//删除变量 
//非严格模式:静默失败 
//严格模式:抛出 ReferenceError
var color= "red";
delete color;
3. 对象

在严格模式下操作对象比在非严格模式下更容易导致错误。
一般来说,非严格模式下会静默失败的情形,在严格模式下就会抛出错误。

下列情形操作对象的属性会导致错误:

  • 为只读属性赋值会抛出 TypeError;
  • 对不可配置的(nonconfigurable)的属性使用 delete 操作符会抛出 TypeError;
  • 为不可扩展的(nonextensible)的对象添加属性会抛出 TypeError。

在使用对象字面量时,属性名必须唯一。
对象有两个同名属性,在非严格模式下,属性值是第二个,在严格模式下,会导致语法错误。

4. 函数
  • 严格模式要求命名函数的参数必须唯一。
    重名参数,非严格模式下,没有错误,只能访问第二个参数;严格模式下,抛出语法错误。

  • 在严格模式下,arguments 对象的行为也有所不同。
    在非严格模式下,修改命名参数的值会反映到 arguments 对象中,严格模式下这两个值是完全独立的。

//修改命名参数的值 
//非严格模式:修改会反映到 arguments 中 
//严格模式:修改不会反映到 arguments 中
function showValue(value){
    value = "Foo";
    alert(value); //"Foo" 
    alert(arguments[0]); //非严格模式:"Foo" 严格模式:"Hi"
}
showValue("Hi");
  • 淘汰了 arguments.callee 和 arguments.caller。
    在非严格模式下,这两个属性一个引用函数本身,一个引用调用函数。在严格模式下,访问哪个属性都会抛出 TypeError。
//访问 arguments.callee 
//非严格模式:没有问题 
//严格模式:抛出 TypeError
function factorial(num){
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num-1)
    }
}
var result = factorial(5);
  • 对函数名做出了限制
    不允许用 implements、interface、let、package、private、protected、public、static 和 yield 作为函数名。

  • 只能在脚本的顶级和在函数内部声明函数
    在 if 语句中声明函数会导致语法错误。

//在 if 语句中声明函数 
//非严格模式:将函数提升到 if 语句外部 
//严格模式:抛出语法错误
if (true){
    function doSomething(){
        //... 
    }
}
5. eval()

最大的变化就是它在包含上下文中不再创建变量或函数。

//使用 eval()创建变量
//非严格模式:弹出对话框显示 10
//严格模式:调用 alert(x)时会抛出 ReferenceError
function doSomething(){
    eval("var x=10");
    alert(x);
}

可以在 eval()中声明变量和函数,但这些变量或函数只能在被求值的特殊作用域中有效,随后就将被销毁。

6. eval与arguments

严格模式已经明确禁止使用 eval 和 arguments 作为标识符,也不允许读写它们的值。
在非严格模式下,可以重写 eval,也可以给 arguments 赋值。严格模式下,会导致语法错误。

不能将它们用作标识符,意味着以下几种使用方式都会抛出语法错误:

  • 使用var声明;
  • 赋予另一个值;
  • 尝试修改包含的值,如使用++;
  • 用作函数名;
  • 用作命名的函数参数;
  • 在 try-catch 语句中用作例外名。
7. 抑制this

在非严格模式下,使用函数的 apply() 或 call() 方法时,null 或 undefined 值会被转换为全局对象。
在严格模式下,函数的 this 值始终是指定的值,无论指定的是什么值。

//访问属性
//非严格模式:访问全局属性 
//严格模式:抛出错误,因为 this 的值为 null
var color = "red";
function displayColor(){
    alert(this.color);
}
displayColor.call(null);

传入 null,在非严格模式下,意味着函数的 this 值是全局对象。

8. 其他变化
  • 抛弃了 with 语句
    非严格模式下,with 语句能够改变解析标识符的路径,在严格模式下,使用 with 会导致语法错误。
//with 的语句用法
//非严格模式:允许
//严格模式:抛出语法错误
with(location){
    alert(href);
}
  • 去掉了 JavaScript 中的八进制字面量
//使用八进制字面量 
//非严格模式:值为 8 
//严格模式:抛出语法错误
var value = 010;

修改了 parseInt() 的行为

//使用 parseInt()解析八进制字面量 
//非严格模式:值为 8 
//严格模式:值为 10
var value = parseInt("010");

上一篇:53-附录-ECMAScript Harmony

全书整理版:《Javascript高级程序设计》第3版(总结版)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值