ECMAScript 5 引入了 strict mode ,现在已经被大多浏览器实现(从IE10开始)

一、什么是严格模式

顾名思义,JavaScript 严格模式就是让 JS 代码以更严格的模式执行,不允许可能会引发错误的代码执行。在正常模式下静默失败的代码,严格模式下就会抛出错误。

二、为什么要过渡到严格模式

  1. 严格模式下的代码在运行的时候,更容易通过抛出的错误定位到问题所在的地方
  2. 严格模式能够帮助你编写更符合规范的代码
  3. 消除 JavaScript 语言上一些不合理,比较怪异的行为
  4. 为未来新版本的 JavaScript 做铺垫
  5. 有时候,严格模式下的 JavaScript 代码运行起来更快

三、如何使用

· 脚本文件范围

"use strict"; 放在脚本文件的第一行。整个脚本文件就会以“严格模式”执行。

· 函数作用域范围

"use strict"; 放在函数体的第一行,则整个函数以"严格模式"运行。

文件合并时,写在脚本文件第一行的 "use strict"; 来实现严格模式会失效,可以将脚本文件的代码放在一个立即执行表达式中。

(funciton() {"use strict";...
})()

四、严格模式的具体定义

  1. 严格模式下无法再隐式创建全局变量 也就是,变量必须声明后才能使用,正常模式直接赋值给一个未定义的变量时,会将变量定义为全局变量。
"use strict";
var a = b = 3;  // Uncaught ReferenceError: b is not defined
​
以上代码等于:
var a;
b = 3;
a = b;
​

  1. 禁止 this 关键字指向全局对象 正常模式下,函数中如果没有指明 this 对象,JS 则会将 this 隐式指向为全局对象。如果绑定的值是非对象,将被自动转为对象再绑定上去,而 null 和 undefined 这两个无法转成对象的值,将被忽略。

严格模式下,必须指明 this 的指向对象。如果没有指明的话,this的值为 undefined

var name = "foo";
function func() {"use strict";this.name;  // Uncaught TypeError: Cannot read property 'name' of undefined
}
func();  // 没有加 new 关键字
new func();
​
function func() {return this
}
​
func() // window
func.call(8) // Number {8}
func.call(true) // Boolean {true}
func.call("abcd")  // {"abcd"}
func.call(null) // window
func.call(undefined) // window
​
"use strict"
function func() {return this
}
​
func() // undefined
func.call(8) // 8
func.call(true) // true
func.call(null) //null
func.call(undefined) // undefined

  1. 不允许在函数内部遍历调用栈 禁止使用 arguments.callee、arguments.caller、fn.caller、fn.callee; 在严格模式下,arguments.callee 是一个不可删除属性,而且赋值和读取时都会抛出异常
function func() {"use strict";func.caller;  // 报错func.arguments; // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
}
func()

  1. 禁止向对象的只读属性赋值,禁止删除对象的不可设置属性, 禁止向不可扩展的对象添加属性 无法删除 var 声明的变量。

在正常模式中,给对象的只读属性赋值, 删除对象的不可设置属性,添加不可扩展对象的新属性,会静默失败。

但是在严格模式中,会抛出错误。 另外,字符串的属性 length 也是只读属性,修改后会报错。

"use strict";
var str = "abc"
str.length = 8  // Uncaught TypeError: Cannot assign to read only property 'length' of string 'abc'
​
'use strict';
var obj = Object.defineProperty({}, 'a', {value: 37,writable: false
});
obj.a = 123; // Uncaught TypeError: Cannot assign to read only property 'a' of object '#
​
'use strict';
var obj = Object.defineProperty({}, 'p', {value: 37,configurable: false
});
delete obj.p  // Uncaught TypeError: Cannot delete property 'p' of #<Object>
​
var obj = {};
Object.preventExtensions(obj);
obj.title = "hello";  // Uncaught TypeError: Cannot add property title, object is not extensible

  1. 对象不允许有重名的属性,函数不允许有重名的参数 在正常模式中,对象的重名属性,位置靠后会覆盖位置靠前的重名属性。函数也是,函数体查找到的参数,靠后的重名参数会覆盖靠前的重名参数。
"use strict";
var o = { p: 1,p: 2};
// IE报错:strict 模式下不允许一个属性有多个定义, 新版的 Chrome 和 firefox 并不会报错,会采用覆盖机制。
​
"use strict";
function func(a, a) {console.log(a)
}
func(1, 2) // IE报错: strict 模式下不允许正式参数名称重复。新版的 Chrome 和 firefox 并不会报错,会采用覆盖机制。

  1. 静态绑定 JavaScript 支持动态绑定,也就是 JavaScript 的属性和方法是在运行时确定,而不是在编译时确定。 于是,JavaScript 严格模式禁用了 with 语句, 因为使用了 with 语句,with 语句块中变量无法确定是外部全局变量还是传入的对象属性。
"use strict";
var x = 17;
with (obj) // !!! 语法错误
{// 如果没有开启严格模式,with 中的这个x会指向 with 上面的那个 x,还是obj.x?// 如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会变慢。x; // Uncaught SyntaxError: Strict mode code may not include a with statement
}

eval 关键字不再会给上层函数(surrounding function)或者全局引入一个新的变量。在严格模式中,eval 语句会创建自己的一个作用域,eval 里的变量只能在 eval 内部使用。

  1. arguments 的限定 严格模式规定名称为 eval 和 arguments 不能通过程序语法被绑定(be bound)或赋值 严格模式下,参数的值不会随 arguments 对象的值的改变而变化。

正常模式中,对参数重新赋值,会修改 arguments 类数组对象下的参数值。同时,修改 arguments 类数组对象的值,也会修改函数参数的值。

严格模式下,不仅参数的值不会随着 arguments 类数组对象的变化而变化,参数的变化也不会引起 arguments 对象的变化,arguments 对象会记住参数的传入初始值。

function func(a) {"use strict"a = 8;// arguments[0] = 8return [a, arguments[0]]
}
​
func(3) // [8, 3]
​
function func(a) {"use strict"arguments[0] = 8return [a, arguments[0]]
}
​
func(3) // [3, 8]

  1. ES5禁止在非函数代码块声明函数 ES5 的严格模式只允许在全局作用域或函数作用域声明函数。也就是说,不允许在非函数的代码块内声明函数。
if (true) {function add() {}
}
add()for (var i = 0; i < 5; i++){function f2() { } // !!! 语法错误f2();
}以上代码在严格模式是禁止的,但是在 ES6 中,是允许在代码块中声明函数的。

  1. 保留关键字 严格模式中一部分字符变成了保留的关键字。这些字符包括implements, interface, let, package, private, protected, public, staticyield。在严格模式下,你不能再用这些名字作为变量名或者形参名
function private() {"use strict" }  //Uncaught SyntaxError: Unexpected strict mode reserved word

  1. 严格模式禁止八进制数字语法

五、向严格模式过渡

严格模式能够帮助我们写出更安全,更有规范的代码,则应该避免一些危险的写法,采用更好的写法:

  1. 变量先声明,再使用,
  2. this 应该在指向自己创建的对象时使用。
  3. arguments 应该在函数第一行就拷贝出来。

六、严格模式的缺点

  1. 现在的代码都会进行文件压缩和合并,此时严格模式就会失效。

总结

现在的 webpack 会在打包的时候默认是严格模式,所以现在不用再手动写 use strict了。严格模式能帮助我们以更规范的方式书写代码,但是无论是否严格模式,都应该注意代码的规范,避免隐式 bug 的出现。

2018/02/08 @Starbucks

欢迎关注我的个人公众号“谢南波”,专注分享原创文章。

为什么有时优盘是只读模式_JS专题之严格模式相关推荐

  1. Redis专题-集群模式

    在redis持久化方式一文中,我们已经提到为了防止数据丢失,redis提供了RDB和AOF两种方式持久化数据,将内存的数据持久化到磁盘上.但是当出现服务器出现故障,比如服务磁盘坏掉导致数据不可恢复时. ...

  2. viewobject_只读ViewObject和声明性SQL模式

    viewobject 介绍 声明式SQL模式被认为是基于实体的视图对象的最有价值的优点之一. 在这种模式下,根据UI中显示的属性在运行时生成VOSQL. 例如,如果某个页面包含一个只有两列Employ ...

  3. 只读ViewObject和声明性SQL模式

    介绍 声明式SQL模式被认为是基于实体的视图对象的最有价值的优点之一. 在此模式下,根据UI中显示的属性在运行时生成VO的SQL. 例如,如果某个页面包含一个只有两列EmployeeId和FirstN ...

  4. 【电源专题】开关模式电源电流检测——电流检测方法

    在[电源专题]开关模式电源电流检测基础及感应电阻放置位置选择中我们说到,开关模式电源有三种常用电流检测方法是:使用检测电阻,使用MOSFET RDS(ON),以及使用电感的直流电阻(DCR).那么这三 ...

  5. 关于python文件打开模式的描述_【单选题】关于Python文件打开模式的描述,以下选项中描述错误的是 A. 覆盖写模式w B. 追加写模式a C. 创建写模式n D. 只读模式r...

    [单选题]关于Python文件打开模式的描述,以下选项中描述错误的是 A. 覆盖写模式w B. 追加写模式a C. 创建写模式n D. 只读模式r 更多相关问题 [单选,A2型题,A1/A2型题] 上 ...

  6. js对象赋值只保留存在的属性_js对象的创建对象模式和继承模式(上)---构建对象模式...

    ​前言 ECMAScript与其他面向对象语言不同的是,它没有类的概念,因此它的对象也和基于类的语言中的对象有所不同,深入理解js的对象是每个前端工程师的基本素养,本文将就创建对象模式的方面对对象进行 ...

  7. Python还原CryptoJs_DES_CBC模式_js逆向学习

    Python_CryptoJs_js逆向破解 一.前言 1.Redeme 二.对称加密解密DES 1.对称加密与非对称加密 2.DES对称加密介绍 3.实现DES的4种模式 4.关于补位PKCS7和P ...

  8. js正则贪婪模式_JS关于正则的非贪婪模式

    首先正则是很复杂,很巧妙的. 你举的这个例子说明贪婪模式和非贪婪模式是不对的. 啥是贪婪模式,和非贪婪模式? 贪婪模式,就是"贪得无厌",有了还要,有多少要多少,指导没有(字符串尾 ...

  9. js正则贪婪模式_js 正则表达式 贪婪与惰性

    首先引入一个介绍比较详细的网站 http://www.jb51.net/article/31491.htm 接下来是本人的简介 其实贪婪和惰性很容易理解,从字面意思我们就可以知道,所谓的"贪 ...

最新文章

  1. linux下刻录iso,linux刻录iso
  2. 2019年9月全国程序员工资统计,看看你拖后腿了没?
  3. 【Python基础】科学计算库Scipy简易入门
  4. 分分钟手写http server
  5. 梦想中的网络安全和内部协作
  6. git提交代码时报错:nothing added to commit but untracked files present
  7. 组件化与插件化的差别在哪里?附面试题答案
  8. Nginx(二) 反向代理负载均衡
  9. Balder 3D开发系列之--给自定义基本体进行贴图操作
  10. 小D课堂 - 零基础入门SpringBoot2.X到实战_第2节 SpringBoot接口Http协议开发实战_12、SpringBoot2.x文件上传实战...
  11. 【RPC】远程过程调用
  12. Centos7安装jdk1.8
  13. 计算机二级c语言考试真题及答案详解,2021全国计算机二级C语言程序设计历年真题及答案节选...
  14. php视图编辑,word中最适合查看编辑排版效果的视图是什么
  15. linux mbr 转 gpt 数据丢吗,MBR转GPT要重装系统吗?不丢失数据 MBR转GPT分区表教程...
  16. 浅谈大小端(Endian)与位域
  17. 超详细的fiddler教程,从小白到精通(五)❤️
  18. 用二叉树表示家谱关系并实现各种查找功能
  19. Java邮件发送QQ邮箱带附件
  20. C++ GUI Programming with Qt4 Second Edition 之 前言

热门文章

  1. mysql hex 和 c_什么是MySQL HEX()函数,它与CONV()函数有何不同?
  2. java语言sql接口_Java语言SQL接口
  3. java aspose 导出word_使用aspose.word 第三方的插件实现导出word
  4. Python数模笔记-Sklearn(2)聚类分析
  5. mingw linux socket,MingW上编译WinSocket程序undefined reference to `WSAStartup@8'报错的解决办法...
  6. python集合操作班级干部竞选演讲稿_精选竞选班干部的演讲稿集合7篇
  7. java userdao,Java Web 开发基础------DAO
  8. dqn系列梳理_系列论文阅读——DQN及其改进
  9. 量子计算机怎么算有用,如何在量子计算机上实现经典计算
  10. pdf.js 文字丢失问题 .cmaps