JavaScript的严格模式

栏目: JavaScript · 发布时间: 5年前

内容简介:ES5最早引入了使用在严格模式下,什么时候创建变量以及怎么创建变量都是有限制的。

ES5最早引入了 严格模式 的概念。通过严格模式,可以在函数内部选择较为严格的全局或局部的错误条件检测。使用严格模式的 好处 是,可以提早地发现函数内部存在的错误以及编译中产生的错误。 支持严格模式的浏览器包括 IE10+、FireFox4+、Safari5.1+和Chrome

二、选择使用

使用 编译指示 ,实际上就是一个字符串: "use strict"; 如果在全局作用域中(函数外部)使用这个编译指示,则整个脚本都将使用严格模式。 也就是说,如果把带有严格模式的脚本放在其他文件中,那么这个文件下的JS代码也会处于严格模式下。 也可以在函数中打开严格模式,

function fn() {
    "use strict";
    // more codes
}
复制代码

三、变量

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

1. 必须声明

不允许意外创建全局变量,必须要有一个声明。

var msg = "Hello!";
复制代码

2. 不能使用delete操作符

不能对变量调用delete操作符。在非严格模式下会静默失败,但是不会报错。而在严格模式下会报错。

3. 变量名不能使用保留字

严格模式下,不能使用implements、interface、let、package、private、protected、public、static、yield等保留字作为变量名。

四、对象

在非严格模式下,操作对象时有些错误会静默失败,而在严格模式下就会报错。 以下情况时操作对象会报错:

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

另外严格模式下,在通过对象字面量形式来声明对象时, 属性名必须唯一 ,否则会报错。

var person = {
    name: 'Knight',
    name: 'Bill'
} // Error
复制代码

五、函数

1. 参数必须唯一

function add(a, a) { 
// dosomething 
}
复制代码

解析: 上面这段函数声明在非严格模式下是不会报错的。 严格模式下,通过参数名只能访问第二个参数,第一个参数必须通过**arguments对象(形参列表)**进行访问。

2. arguments对象的命名参数

在严格模式下,arguments对象的行为和非严格模式是有区别的。 在非严格模式下,修改命名参数的值会反映到arguments对象中,但是在严格模式下这两个值是 相互独立 的。

function showName(name) {
    name = 'Mike',
    console.log(name); // 'Mike'
    console.log(arguments[0]); // 非严格模式:'Mike'; 严格模式: 'Bill'
}
showName('Bill');
复制代码

解析:在调用函数时,首先会传入实参值'Bill',并写入arguments对象中。 在非严格模式下,函数内部将name值重新赋值为'Mike',因此arguments[0]的值也被同时修改为'Mike'。 而在严格模式下,arguments[0]的值依然是'Bill'。

3. arguments对象的callee和caller

在非严格模式下,这两个属性一个引用 函数本身 ,一个引用 调用函数 。 而在严格模式下,这两个属性被淘汰,使用时均会报错。

// 求一个阶乘
function fn(num) {
    if(num <= 1) {
        return 1;
    }else {
        return num * arguments.callee(num-1);
    }
}
console.log(fn(3)); // 3! = 6
复制代码

解析: 这是一个求阶乘的函数,在非严格模式下,调用函数时,可用arguments.callee()来调用函数本身,从而实现函数功能。 而在严格模式下则会报错。

4. 函数名不允许用保留字

严格模式下,不能使用implements、interface、let、package、private、protected、public、static、yield等保留字作为函数变量名。

5. 禁止不在脚本或者函数层面上的函数声明

在严格模式下,只能在脚本的顶级和在函数内部声明函数。也就是说,在if语句/for语句中,声明函数是会报错的。

"use strict";
if (true) {
  function f() { } // !!! 语法错误
  f();
}

for (var i = 0; i < 5; i++) {
  function f2() { } // !!! 语法错误
  f2();
}

function baz() { // 合法
  function eit() { } // 同样合法
}
复制代码

六、eval()

eval()在 包含上下文 中不再创建变量和函数。

function fn() {
    eval("var x = 123;");
    console.log(x);
}
fn();
复制代码

解析:上述代码在严格模式下是会报错的(ReferenceError),而在非严格模式下正常运行。

七、eval与arguments

严格模式不允许使用eval和arguments作为标识符,也不允许读写它们的值。

var eval = 'hello';
var arguments = 'world';
复制代码

解析:这在非严格模式下是可以解析运行的,但是在严格模式下会报错。 因此,不能将它们用作标识符,以下几种情况均会抛出语法错误:

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

八、抑制this

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

var color = "red";
function displayColor() {
    console.log(this.color);
}
displayColor.call(null);
复制代码

解析: 在非严格模式下,displayColor.call()中传入了null,那么此时函数的this是全局对象,因此会打印出red。 而在严格模式下,这个函数的this就是null,因此在访问null的属性时会报错。

九、其他变化

1. 抛弃with语句

非严格模式下,with语句可以改变解析标识符的路径,但是在严格模式下,with被简化,会报错。

with(location) {
    alert(href);
}
复制代码

2. 抛弃八进制字面量

以0开头的八进制字面量过去经常会导致很多错误。 因此,在严格模式下,八进制字面量已经被抛弃。

var val = 010;
复制代码

3. parseInt()的变化

在ES5标准的严格模式下,八进制字面量会被当做以0开头的十进制字面量。

var val = parseInt("010");
console.log(val); // 10
复制代码

以上所述就是小编给大家介绍的《JavaScript的严格模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Mission Python

Mission Python

Sean McManus / No Starch Press / 2018-9-18 / GBP 24.99

Launch into coding with Mission Python, a space-themed guide to building a complete computer game in Python. You'll learn programming fundamentals like loops, strings, and lists as you build Escape!, ......一起来看看 《Mission Python》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具