原文:地址一
原文:地址二
一、严格模式的使用:
严格模式的使用很简单,只有在代码首部加入字符串 "use strict"。必须在首部即首部指其前面没有任何有效js代码除注释,否则无效;
二、严格模式的注意事项与特点:
(1)不使用var声明变量严格模式中将不通过,在循环中如果没有声明变量在非严格模式中很危险,变量会不小心溢出成为全局变量,但在严格模式中会报错,严格模式中变量必须显示声明(var/let/const);
(2)JS中作用域有两种,全局作用域和函数作用域。严格模式带来了第三种作用域:eval作用域,则任何使用'eval'的操作都会被禁止,(eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码,不常用容易报错),在严格模式下,arguments和eval是关键字,不能被修改,不能做变量处理;
(3)with()被禁用:with 语句用于设置代码在特定对象中的作用域。with 语句是运行缓慢的代码块,尤其是在已设置了属性值时。大多数情况下,如果可能,最好避免使用它;
(4)caller/callee 被禁用;
(5)对禁止扩展的对象添加新属性会报错:Object.preventExtensions(obj);然后对obj增加属性则会报错;
(6)删除系统内置的属性会报错;
(7)delete使用var声明的变量或挂在window上的变量报错;
(8)delete不可删除属性(isSealed或isFrozen)的对象时报错(Object.isSealed() 方法判断一个对象是否被密封。Object.isFrozen()方法判断一个对象是否被冻结。);
(9)对一个对象的只读属性进行赋值将报错(Object.defineProperty(obj, 'a', {value: 1, writable: false})然后对obj属性修改则会报错);
(10)对象有重名的属性将报错;
(11)函数有重名的参数将报错,在严格模式下,函数的形参也不可以同名;
(12)八进制表示法被禁用;
(13)arguments严格定义为参数,不再与形参绑定;
(14)一般函数声明都在最顶层,ES5前的JS宽松,你可以写在if或for内(强烈鄙视这种写法)。当然Firefox的解析方式与其他浏览器不同,而在严格模式中这些写法将直接报错;
(15)ES6里新增的关键字不能当做变量标示符使用,如implements, interface, let, package, private, protected, public, static, yield;
(16)call/apply的第一个参数直接传入不包装为对象;
(17)call/apply/bind的第一个参数为null/undefined时,this为null/undefined;
来张比较直观的图示区分二者的区别:
严格模式 | 非严格模式 |
---|---|
禁止使用with语句 | 允许使用with语句 |
所有变量要先声明 | 使用未声明的变量将隐式声明为全局变量 |
函数(非方法)中的this 是undefined |
this 是全局对象 |
call() 和apply() 传入的第一个值不会被转换 |
call() 和apply() 传入的第一个值如果是null 和undefined ,则会被全局对象取代,如果是原始值则转换为对应的包装对象 |
给只读属性和不可扩展的对象创建新成员将抛出类型错误异常 | 只是简单的操作失败 |
传入eval() 的代码不能在定义变量和函数 |
变量和函数定义在eval() 创建的新作用域中 |
函数中的arguments 对象拥有传入函数值的静态副本 |
|
delete 后跟非法标识符将抛出语法错误异常 |
只是简单的返回false |
delete 删除不可配置的属性将抛出类型错误异常 |
只是简单的返回false |
在对象直接量中定义多个同名属性将产生语法错误 | 不会报错 |
函数声明存在多个同名的参数将产生语法错误 | 不会报错 |
不允许使用八进制直接量 | 某些实现是允许的 |
eval 和arguments 当作关键字,并且不允许更改 |
|
限制了对栈的检测能力,arguments.caller 和arguments.callee 将抛出类型错误异常 |
以上便是严格模式与非严格模式的特点与不同点。
巴拉巴拉: