Js严格模式
Js严格模式
JavaScript
严格模式strict mode
,即在严格的条件下运行。严格模式消除了Javascript
语法的一些不合理、不严谨之处,减少一些怪异行为;消除代码运行的一些不安全之处,保证代码运行的安全;提高了引擎的效率,增加运行速度;为未来新的Js
版本做好铺垫。
实例
针对整个脚本文件启用严格模式
"use strict";
x = 1; // Uncaught ReferenceError: x is not defined
针对函数作用域启用严格模式
x = 1;
function s(){
"use strict";
y = 1; // Uncaught ReferenceError: y is not defined
}
s();
严格模式的限制
不允许直接声明全局变量
// 非严格模式
x = 1;
console.log(window.x); // 1
// 严格模式
"use strict";
var x = 1; // 可以使用var在全局作用域声明全局变量
y = 1; // Uncaught ReferenceError: y is not defined
不允许delete变量和函数
// 非严格模式
var x = 1;
delete x;
console.log(window.x); // undefined
// 严格模式
"use strict";
var x = 1;
delete x; // Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
要求函数的参数名唯一
// 非严格模式
function s(a, a){
console.log(a + a); // 6
}
s(2, 3);
// 严格模式
"use strict";
function s(a, a){ // Uncaught SyntaxError: Duplicate parameter name not allowed in this context
console.log(a + a);
}
s(2, 3);
不允许使用八进制数字语法
// 非严格模式
var x = 010;
console.log(x); // 8
// 严格模式
"use strict";
var y = 010; // Uncaught SyntaxError: Octal literals are not allowed in strict mode.
var x = 0O10; // 可以使用ES6中的八进制表示法新写法 前缀0o或0O
console.log(x); // 8
不允许使用转义字符
// 非严格模式
var x = " 45";
console.log(x); // %
// 严格模式
"use strict";
var x = " 45"; // Uncaught SyntaxError: Octal escape sequences are not allowed in strict mode.
不允许对只读属性操作
// 非严格模式
// 操作静默失败,即不报错也没有任何效果
// 给不可写属性赋值
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});
obj.x = 1;
console.log(obj.x); // 0
// 给只读属性赋值
var obj = {
_x: 0,
get x() { return this._x; }
};
obj.x = 1;
console.log(obj.x); // 0
// 给不可扩展对象的新属性赋值
var obj = {};
Object.preventExtensions(obj);
obj.x = 1;
console.log(obj.x); // undefined
// 严格模式
// 操作失败抛出异常
"use strict";
// 给不可写属性赋值
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});
obj.x = 1; // Uncaught TypeError: Cannot assign to read only property 'x' of object '#<Object>'
// 给只读属性赋值
var obj = {
_x: 0,
get x() { return this._x; }
};
obj.x = 1; // Uncaught TypeError: Cannot set property x of #<Object> which has only a getter
// 给不可扩展对象的新属性赋值
var obj = {};
Object.preventExtensions(obj);
obj.x = 1; // Uncaught TypeError: Cannot add property x, object is not extensible
不允许使用保留关键字命名变量
// 非严格模式
var eval = 1;
console.log(eval); // 1
// 严格模式
"use strict";
var eval = 1; // Uncaught SyntaxError: Unexpected eval or arguments in strict mode
不允许使用with关键字
// 非严格模式
var obj = { x:0 };
with(obj) {
x = 1;
}
// 严格模式
"use strict";
var obj = { x:0 };
with(obj) { // Uncaught SyntaxError: Strict mode code may not include a with statement
x = 1;
}
eval声明变量不能在外部使用
// 非严格模式
eval("var x = 0");
console.log(x); // 0
// 严格模式
"use strict";
eval("var x = 0"); // eval作用域
console.log(x); // Uncaught ReferenceError: x is not defined
arguments保留原始参数
// 非严格模式
function s(a, b){
a = 2;
console.log(arguments[0], arguments[1]); // 2 2
}
s(1, 2);
// 严格模式
"use strict";
function s(a, b){
a = 2;
console.log(arguments[0], arguments[1]); // 1 2
}
s(1, 2);
this的限制
在严格模式下通过this
传递给一个函数的值不会被强制转换为一个对象。对一个普通的函数来说,this
总会是一个对象:不管调用时this
它本来就是一个对象;还是用布尔值,字符串或者数字调用函数时函数里面被封装成对象的this
;还是使用undefined
或者null
调用函数式this
代表的全局对象(使用call
,apply
或者bind
方法来指定一个确定的this
)。这种自动转化为对象的过程不仅是一种性能上的损耗,同时在浏览器中暴露出全局对象也会成为安全隐患,因为全局对象提供了访问那些所谓安全的JavaScript
环境必须限制的功能的途径。所以对于一个开启严格模式的函数,指定的this
不再被封装为对象,而且如果没有指定this
的话它值是undefined
。
// 非严格模式
function s(){
console.log(this); // Window ...
}
s();
// 严格模式
"use strict";
function s(){
console.log(this); // undefined
}
s();
禁止访问调用栈
在严格模式中再也不能通过广泛实现的ECMAScript
扩展游走于JavaScript
的栈中。在普通模式下用这些扩展的话,当一个叫fun
的函数正在被调用的时候,fun.caller
是最后一个调用fun
的函数,而且fun.arguments
包含调用fun时用的形参。这两个扩展接口对于安全JavaScript
而言都是有问题的,因为他们允许安全的代码访问专有函数和他们的(通常是没有经过保护的)形参。如果fun
在严格模式下,那么fun.caller
和fun.arguments
都是不可删除的属性而且在存值、取值时都会报错。
// 非严格模式
function ss(){
console.log(ss.caller); // ƒ s(){ ss(); }
console.log(ss.arguments); // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
function s(){
ss();
}
s();
// 严格模式
"use strict";
function ss(){
console.log(ss.caller); // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
console.log(ss.arguments); // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them ƒ]
}
function s(){
ss();
}
s();
参考
https://www.runoob.com/js/js-strict.html
https://www.cnblogs.com/xumqfaith/p/7841338.html
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode
- C#线程篇---解答线程之惑(2)
- webpack学习(三)html-webpack-plugin插件
- Codevs2018 反病毒软件
- 2953: [Poi2002]商务旅行
- 1230: [Usaco2008 Nov]lites 开关灯
- 【推荐】C#线程篇---你所不知道的线程池(4)
- 洛谷P1333 瑞瑞的木棍(欧拉回路)
- 【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.1)
- 【LeetCode 20】关关的刷题日记45 – Valid Parenthese
- 1819: [JSOI]Word Query电子字典
- 【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.2)
- javascript 事件基础
- 算法模板——sap网络最大流 3(递归+邻接矩阵)
- 从Hash Killer I、II、III论字符串哈希
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法