你可能不知道系列--JavaScript严格模式与非严格模式的区别
对于 JavaScript
严格模式与非严格模式的区别,强烈建议大家去查看权威文档 MDN: 严格模式,不要乱找百度,本文也主要是参考了 MDN
上对 JS 严格模式
的介绍。
首先,严格模式通过抛出错误来消除一些原有的静默错误。
其次,严格模式修复了一些导致JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行的更快。
第三,严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
1、使用严格模式
- 函数中使用
funtion () {'use strict'; //或者是"use strict";
}
- 整个脚本中使用:在这个JavaScript文件开头写
'use strict';
(或者是"use strict";
)
2、怎么合理的使用严格模式
不推荐在整个脚本中使用严格模式
,这种语法存在缺陷,有一个大型网站已经被坑倒了。试想合并一个严格模式的脚本和一个非严格模式的脚本:合并后脚本的代码看起来是严格模式。反之亦然:非严格合并严格看起来是非严格的。
严格与严格,非严格与非严格合并都没问题,只有严格与非严格合并是有可能有问题。建议按照一个个函数去开启严格模式。
你可以将整个脚本的内容用一个函数包括起来,然后在这个外部函数中使用严格模式。这样就可以消除合并的问题,但是这就意味着您必须要在函数作用域外声明一个全局变量。
3、严格模式与非严格模式的不同
1.严格模式下,不允许使用with
。
!function () {with({ x: 1 }) {console.log(x); //1}
}()!function () {'use strict';with({ x: 1 }) {console.log(x); //SyntaxError}
}()
一种取代 with 的简单方法
是,将目标对象赋给一个短命名变量,然后访问这个变量上的相应属性。
p.s.:解释下!function () {}();
解释器在解释一个语句时,如果以function开头,就会理解为函数声明。
而前面加一个"!"
可以让解释器理解为函数表达式,这样就可以立即调用
了。
2.严格模式下,不允许给未声明的变量赋值
。
3.严格模式下,arguments变为参数的静态副本。
非严格模式下,arguments对象里的元素和对应的参数是指向同一个值的引用
!function(a) {arguments[0] = 100;console.log(a); //100
}(1);!function(a) {'use strict';arguments[0] = 100;console.log(a); //1
}(1);
但是:传的参数
是对象
除外。arguments和形参共享传递。
!function(a) {'use strict';console.log(a.x); //1arguments[0].x = 100;console.log(a.x); //100
}({x: 1});
4.严格模式下,删除参数名,函数名报错
。非严格模式返回false,静默失败。(静默失败:不报错也没有任何效果)
!function(a) {console.log(a); //1console.log(delete a); //falseconsole.log(a); //1
}(1);!function(a) {'use strict';console.log(a); //1delete a; //SyntaxError(语法错误)console.log(a); //1
}(1)
5.严格模式下,函数参数名重复报错
。非严格模式最后一个重名参数会覆盖之前的重名参数。
!function (a, a, b) {console.log(a + b); //5
}(1, 2, 3);!function (a, a, b) {'use strict';console.log(a + b); //SyntaxError
}(1, 2, 3);
6.严格模式下,删除不可配置(configurable=false)的属性报错
。非严格模式返回false,静默失败。
!function (a){var obj={};Object.defineProperty(obj,'a',{ configurable: false });console.log(delete obj.a); //flase
}(1); !function (a){'use strict';var obj={};Object.defineProperty(obj, 'a', { configurable: false });console.log(delete obj.a); //TypeError
}(1);
7.严格模式下,修改不可写(writable=false)的属性报错
。
!function () {var obj = { a: 1 };Object.defineProperty(obj, 'a', { writable: false });obj.a = 2;console.log(obj.a); //1 //证明没有被修改
}();!function () {'use strict';var obj = { a: 1 };Object.defineProperty(obj, 'a', {writable: false});obj.a = 2; //TypeError
}();
8.严格模式下,对象字面量重复属性名报错
。
!function() {var obj = { x: 1, x: 2 };console.log(obj.x); //2}();!function() {'use strict';var obj = { x: 1, x: 2 }; console.log(obj.x); //IE10+报错。IE7~9、Chrome、FF不报错,结果为:2
}();
亲测:IE10+报错:strict 模式下不允许一个属性有多个定义。IE7~9,Chrome,FF不报错。其他浏览器未测。
9.严格模式下,禁止八进制字面量
。
!function (){console.log(0123); //83
}();!function (){'use strict';console.log(0123); //SyntaxError
}();
10.严格模式下,eval,arguments成为关键字,不能用作变量,函数名
。
11.严格模式下,eval变成了独立作用域
。
!function() {eval('var evalVal = 2;');console.log(typeof evalVal); //number
}();!function() {'use strict';eval('var evalVal = 2;');console.log(typeof evalVal); //undefined
}();
12.严格模式下,给只读属性赋值报错
。
!function () {'use strict';var obj = { get x() { return 17; } };obj.x = 5; //TypeError
}();
13.严格模式下,给不可扩展对象的新属性赋值报错
。
!function () {'use strict';var fixed = { oldProp: "hello" };Object.preventExtensions(fixed);fixed.newProp = "world"; //TypeError
}();
14.ES6中,严格模式下,禁止设置五种基本类型值的属性
。
!function () {'use strict';undefined.aaa = 'aaa'; //TypeErrornull.bbb = 'bbb'; //TypeErrorfalse.ccc = 'ccc'; //TypeError(123).ddd = 'ddd'; //TypeError"hello".eee = 'eee'; //TypeError
}();
12.严格模式下,一般函数调用(不是对象的方法调用,也不使用apply/call/bind等修改this),this指向undefined,而不是全局对象
。
!function () {function fun() { return this; }console.log( fun() ); //Window
}();!function () {'use strict';function fun() { return this; }console.log( fun() ); //undefined
}();
注意:这一点网上好多说的是this
会指向null
,这是不对的,查看了MDN之后,上面明确写出this
指向undefined
。Chrome下亲测也是如此。
13.严格模式下,使用apply/call/bind,当传入参数是null/undefined时,this指向null/undefined,而不是全局对象
。
!function () {function fun() { return this; }console.log( fun.apply(null) ); //Windowconsole.log( fun.apply(undefined) ); //Windowconsole.log( fun.call(null) ); //Windowconsole.log( fun.call(undefined) ); //Windowconsole.log( fun.bind(null)() ); //Windowconsole.log( fun.bind(undefined)() ); //Window
}();!function () {'use strict';function fun() { return this; }console.log( fun.apply(null) ); //nullconsole.log( fun.apply(undefined) ); //undefinedconsole.log( fun.call(null) ); //nullconsole.log( fun.call(undefined) ); //undefinedconsole.log( fun.bind(null)() ); //nullconsole.log( fun.bind(undefined)() ); //undefined
}();
14.严格模式下,不再支持arguments.callee
。非严格模式下,arguments.callee指向当前正在执行的函数。这个作用很小:直接给执行函数命名就可以了!此外,arguments.callee 十分不利于优化,例如内联函数,因为 arguments.callee 会依赖对非内联函数的引用。在严格模式下,arguments.callee 是一个不可删除属性,而且赋值和读取时都会抛出异常:
!function () {'use strict';var fun = function () { return arguments.callee; };fun(); //TypeError
}();
15.严格模式下,不再支持arguments.caller
。在一些旧时的ECMAScript实现中arguments.caller曾经是一个对象,里面存储的属性指向那个函数的变量。这是一个安全隐患,因为它通过函数抽象打破了本来被隐藏起来的保留值;它同时也是引起大量优化工作的原因。出于这些原因,现在的浏览器没有实现它。但是因为它这种历史遗留的功能,arguments.caller在严格模式下同样是一个不可被删除的属性,在赋值或者取值时会报错:
!function () {"use strict";function fun(a, b) {var c = 12;return arguments.caller; //IE10+报错。IE7~9、Chrome、FF不报错。}console.log(fun(1, 2)); //在不报错的浏览器下,结果是:undefined
}();
亲测:IE10+报错:strict 模式下不允许访问函数或参数对象的“caller”属性。IE7~9、Chrome、FF不报错。其他浏览器未测。
16.严格模式下,一些保留字
。
在严格模式中一部分字符变成了保留的关键字。这些字符包括implements
, interface
, let
, package
, private
, protected
, public
, static
和 yield
。在严格模式下,你不能再用这些名字作为变量名或者形参名。
17.严格模式下,禁止了不在脚本或者函数层面上的函数声明
。
!function () {"use strict";if (true) {function fun() {}console.log( fun() ); //IE10报错。IE11、IE7~9、Chrome、FF不报错。}for (var i = 0; i < 5; i++) {function fun2() {}console.log( fun2() ); //IE10报错。IE11、IE7~9、Chrome、FF不报错。}function fun3() { // 合法function fun4() {} //同样合法}
}();
亲测:IE10报错。IE11、IE7~9、Chrome、FF不报错。其他浏览器未测。
主流浏览器现在实现了严格模式。但是不要盲目的依赖它,因为市场上仍然有大量的浏览器版本只部分支持严格模式或者根本就不支持。谨慎地使用严格模式!
以上 ?
你可能不知道系列--JavaScript严格模式与非严格模式的区别相关推荐
- (JavaScript)贪婪模式和非贪婪模式(懒惰模式)
文章目录 概念 一.贪婪模式与非贪婪模式的内容 二.代码 1.贪婪模式 2.非贪婪模式(懒惰模式) 概念 贪婪和非贪婪(懒惰): JavaScript中正则表达式默认是贪婪的,改成非贪 ...
- Python正则表达式中的贪心模式和非贪心模式
声明:最近发现有人利用我在百度云盘里免费分享的127课Python视频盈利,并声称获得我的授权.在此,我声明,文末百度云盘里的Python视频是免费的,不会授权给任何人或机构进行销售.如果再发现有人卖 ...
- python 正则表达式贪婪模式与非贪婪模式
1 贪婪模式与非贪婪模式 的理解 1.1 贪婪模式: 是尽可能的多地匹配字符 ,贪婪模式一般是在元符号后面没有添加? 1.2 非贪婪模式(懒惰模式): 是尽可能的少匹配字符,非贪婪模式一般是元符号后面 ...
- java 正则表达式 非贪婪模式_详解正则表达式的贪婪模式与非贪婪模式
什么是正则表达式的贪婪与非贪婪匹配 如:String str="abcaxc"; Patter p="ab*c"; 贪婪匹配:正则表达式一般趋向于最大长度匹配, ...
- oracle归档模式教程,Oracle从归档模式变成非归档模式详细步骤
更改Oracle数据库的非归档模式需要重新启动数据库,在mount模式下修改,简要步骤1 以shutdown immediate方式关闭数据库2 启动实 Oracle从归档模式变成非归档模式详细步骤 ...
- mysql 5.6 gtid mha_MySQL MHA--故障切换模式(GTID模式和非GTID模式)
GTID和非GTID故障切换模式选择 MySQL 5.6版本引入GTID来解决主从切换时BINLOG位置点难定位的问题,MHA从0.56版本开始支持基于GTID的复制,在切换时可以采用GTID模式和非 ...
- 网络嗅探混杂模式与非混杂模式的区别
1.混杂模式与非混杂模式的区别: 这两种方式区别很大.一般来说,非混杂模式的嗅探器中,主机仅嗅探那些跟它直接有关的通信,如发向它的,从它发出的,或经它路由的等都会被嗅探器捕捉.而在混杂模式中则嗅探传输 ...
- python与正则表达式(part3)--贪婪模式和非贪婪模式
文章目录 贪婪模式和非贪婪模式 定义 贪婪模式转换为非贪婪模式 贪婪模式和非贪婪模式 定义 贪婪模式: 默认情况,在整个表达式匹配成功的前提下,尽可能多的匹配. 非贪婪模式(懒惰模式): 在整个表达式 ...
- 正则表达式的贪婪模式、非贪婪模式、占有模式
文章目录 一.Greediness(贪婪型) (一)贪婪模式示例 (二)贪婪模式的匹配过程(贪婪模式的回溯) 二.Reluctant(勉强型) (一)非贪婪模式示例 (二)非贪婪模式的匹配过程 三.P ...
最新文章
- SSH pager-taglib分页的实现
- pip安装库包遇到错误:TypeError: expected str, bytes or os.PathLike object, not int 的解决方法
- js中用tagname和id获取元素的3种方法
- linux——rpm的详细说明
- 九、“行胜于言车胜马,负重致远向前途”
- 率土之滨鸿蒙之初,率土之滨:最记仇联盟?投诚玩家结算前被乱世,称是主盟要求...
- 【算法】广度遍历算法的应用 求出距离顶点v0的最短路径长度为最长的一个顶点,图结构的bfs生成树及其双亲表示形式
- MFC的静态库.lib、动态库.dll(包含引入库.lib)以及Unicode库示例
- javascript OOP 面向对象编程
- postman安装路径_OpenStack Swift 安装及使用
- Activiti学习(二)数据表结构
- Android给TextView和EditText等控件设置透明背景、圆角边框
- Chrome 新 UI 很“难看”,用户很生气
- Hibernate标准查询
- 易语言服务器中转,让自己的电脑变成服务器,易语言远程文件传输器
- 61php飞信发送类(phpfetion)v1.5,资源索引 L_PC6下载
- SitePoint Podcast#167:炉边聊天
- SQL 2014新功能介绍系列3 - 备份还原篇
- 微信好友列表服务器,微信小游戏如何实现邀请好友列表
- 关于http请求中使用NameValuePair遇到的坑
热门文章
- 具有网状神经系统的动物,动物学网状神经系统图
- python和php web负载均衡,实现负载均衡使用Python
- 0基础适合新手,5分钟教会你视频剪辑,新手做自媒体短视频必备
- 计算机主板 原理,电脑主板的工作原理
- C语言—atoi()、itoa()函数以及my_atoi()、my_itoa()函数详解
- Revit中绘制弯曲的靠背栏杆和生成过梁
- phpStudy下载安装,PHP项目部署,云服务器项目部署
- H5--新增表单元素控件属性事件
- 计算机学院志愿者组织名称,计算机学院青年志愿者招募令
- pdf中的表格怎么复制到word