javaScript 严格模式

1. “use strict” 开启严格模式

(1)给script标签开启严格模式
(2)给function开启严格模式function() {“use strict”; }

2. 严格模式的不同之处

(1)将拼写错误转换成异常

a. 无法再意外得创建全局变量
"use strict";
var hei;
hie = 1;

Uncaught ReferenceError: hie is not defined

b. 静默失败的赋值抛出异常

静默失败(silently fall):不报错也没有任何效果。给不可写属性赋值,给只读属性赋值,给不可扩展对象的新属性赋值,这些情况都可以引起静默失败。

"use strict";
var fixed = {};
Object.preventExtensions(fixed);
fixed.addProp = "hi";

Uncaught TypeError: Cannot add property newProp, object is not extensible

c. 试图删除不可删除的属性时会抛出异常
"use strict";
delete Object.prototype;

Uncaught TypeError: Cannot delete property ‘prototype’ of function Object() { [native code] }

d. 在Gecko版本34之前,要求一个对象内的所有属性名在对象内是唯一的,现在已经没有这个bug了。
"use strict";
var obj = {p: 1, p: 2};
e. 要求函数的参数名唯一

非严格模式,同名的参数后者会覆盖前者,但是前者还是可以通过 arguments[i] 来访问。在严格模式中,有语法错误

function sum (a, a, c) {
    "use strict";
    return a + b + c;
}

Uncaught SyntaxError: Duplicate parameter name not allowed in this context

f. 禁止八进制数字语法

浏览器支持八进制语法;

var a = 010;
console.log(a); // a = 8;

ES6支持为一个数字加“0”的前缀表示八进制。但是有些开发者会省略掉”0”,这样可能会导致错误,所以严格模式是禁止八进制的。会抛出语法错误。

"use strict";
var a = 010;

Uncaught SyntaxError: Octal literals are not allowed in strict mode.

g. 禁止设置primitive值的属性

不采用严格模式,设置属性的操作会被忽略;采用严格模式,将抛出TypeError错误。
primitive(原始)值或primitive数据类型不是一个对象,没有methods。在JavaScript中,有6种primitive数据类型: string,number, boolean, null, undefined, symbol(ES6)

"use strict";
false.true = '';

Uncaught TypeError: Cannot create property ‘true’ on boolean ‘false’

(2). 简化变量的使用

简化了代码中变量名称映射到变量定义的方式。有利于编译器的优化。

a. 禁止使用with。

with用于设置特定对象的作用域,也就是with块里面的所有变量都是优先在传入的对象属性中查找,找不到再找作用域之外的。

var a = 123;
var b = {a: 321};
with (b) {
    console.log(a); // 321
}
var d = {};
with (d) {
    console.log(a);// 123
}

with引起的问题是块内的任何名称可以映射到with传进来的对象的属性,也可以映射到包围这个块的作用域内的变量,甚至是全局变量,这一切都是在运行时决定的。为了优化,所以禁用了with。

"use strict";
var x = 1;
var obj = {x: 2};
with (obj) {
    console.log(x);
}

Uncaught SyntaxError: Strict mode code may not include a with statement
一种替代with 的方法是,将目标对象赋值给一个短命名变量,然后访问变量上的相应属性。

b. 严格模式下,eval 不再为上层范围(surrounding scope,也就是包围eval代码块的范围)引入新变量。

eval(string),计算某个字符串,并且执行其中的JavaScript代码。

c. 严格模式禁止删除声明变量。

非严格模式

var a = 1;
delete a;
console.log(a); // a = 1

严格模式

"use strict";
var a = 1;
delete a;

Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.

(3). 让eval 和arguments 变得简单

a. 名称eval 和 arguments 不能通过程序语法被绑定或者是赋值。
"use strict";
eval = 17;
arguments ++;

Uncaught SyntaxError: Unexpected eval or arguments in strict mode

b. 严格模式下,参数的值不会随arguments 对象的值改变而改变。

非严格模式下

function f(a) {
    a = 42;
    return [a, arguments[0]];
}
var pair = f(17);
console.log(pair[0]); // 42
console.log(pair[1]);// 42

严格模式下

function f(a) {
    "use strict";
    a = 42;
    return [a, arguments[0]];
}
var pair = f(17);
console.log(pair[0]); // 42
console.log(pair[1]);// 17
c. 不再支持arguments.callee。

非严格模式下,arguments.callee指向当前正在执行的函数。
严格模式下:

"use strict";
function f() {
    return arguments.callee;
}

Uncaught TypeError: ‘caller’, ‘callee’, and ‘arguments’ properties may not be accessed on strict mode functions or the arguments objects for calls to them

(4). 安全的JavaScript

a. 严格模式下通过this传递给一个函数的值,不会被强制性转换为一个对象。如果没有指定this,它的值是undefined。

非严格模式

function fun() {return this;}
console.log(fun()); // Window
console.log(fun().call(2)); // Number
console.log(fun().apply(null)); // Window
console.log(fun().call(undefined)); // Window
console.log(fun().bind(true)); // Boolean

严格模式

"use strict";
function fun() {return this;}
console.log(fun()); // undefined
console.log(fun().call(2)); // 2
console.log(fun().apply(null)); // null
console.log(fun().call(undefined)); // undefined
console.log(fun().bind(true)); // true
b. 严格模式下再也不能通过广泛实现的ECMAScript游走于JavaScript栈中。

比如,一个函数fun 它的 fun.caller(返回最后一个调用fun的函数),fun.arguments都是不可删除的属性,而且在取值和存值的时候会报错。

非严格模式下:

function b() {
    console.log(b.caller);
    console.log(b.arguments);
}
function a() {
    b();
}
a();

输出结果

严格模式下:
Uncaught TypeError: ‘caller’ and ‘arguments’ are restricted function properties and cannot be accessed in this context.

c. 严格模式下arguments不会再提供访问与调用这个函数相关变量的途径。

arguments.caller对象,存储的属性指向那个函数的变量。arguments.caller是不可删除的属性,而且在取值和存值的时候会报错。

非严格模式下:

function fun(a, b) {
    var v = 2;
    return arguments.caller;
}
console.log(fun(1, 2)); // undefined

严格模式:
自己尝试的结果跟非严格模式一样,跟文档中不一样,为啥?

(5). 为未来的ECMAScript版本铺平道路

a. 以下保留字在严格模式下将不能作为变量名或者是形参。

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

b. 严格模式禁止了不在脚本或者是函数层面上的函数声明。

非严格模式下,在哪儿都是可以声明函数的。例如:

var flag = true;
if (flag) {
    function change() {
        flag = false;
    }
    change();
}

在严格模式下,是不建议这么做的。

3.浏览器的严格模式

主流浏览器都已经支持严格模式,但是有大量浏览器版本部分支持或者是根本不支持严格模式。

4. 其他

学习文档: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode
测试浏览器: chrome(Version 60.0.3112.113 (Official Build) (64-bit))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值