📧1 严格模式
严格模式主要有以下限制:
-
变量必须声明后再使用
-
函数的参数不能有同名属性,否则报错
-
不能使用with语句
-
不能对只读属性赋值,否则报错
-
不能使用前缀0表示八进制数,否则报错
-
不能删除不可删除的属性,否则报错
-
不能删除变量delete prop,会报错,只能删除属性delete global[prop]
-
eval不会在它的外层作用域引入变量
-
eval和arguments不能被重新赋值
-
arguments不会自动反映函数参数的变化
-
不能使用arguments.callee
-
不能使用arguments.caller
-
禁止this指向全局对象
-
不能使用fn.caller和fn.arguments获取函数调用的堆栈
-
增加了保留字(比如protected、static和interface)
💞1.1 “use strict” 严格模式
“use strict” 是ES5 中的新指令(ECMAScript version 5)。
“严格模式”体现了Javascript更合理、更安全、更严谨的发展方向,包括IE 10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱它。
💞1.2 开启严格模式
针对脚本
针对函数
优化形式
“use strict”;
// some code here
})();
💞1.3 全局变量显式声明
for(i = 0; i < 2; i++) { // 报错,i未声明
}
💞1.4 静态绑定
严格模式对动态绑定做了一些限制。某些情况下,只允许静态绑定。也就是说,属性和方法到底归属哪个对象,在编译阶段就确定。这样做有利于编译效率的提高,也使得代码更容易阅读,更少出现意外。
具体来说,涉及以下几个方面。
(1)禁止使用with语句
因为with语句无法在编译时就确定,属性到底归属哪个对象。
var v = 1;
with (o){ // 语法错误
v = 2;
}
(2)创设eval作用域
正常模式下,Javascript语言有两种变量作用域(scope):全局作用域和函数作用域。严格模式创设了第三种作用域:eval作用域。
正常模式下,eval语句的作用域,取决于它处于全局作用域,还是处于函数作用域。严格模式下,eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。
var x = 2;
console.info(eval(“var x = 5; x”)); // 5
console.info(x); // 2
💞1.5 增强的安全措施
💞1.6 禁止删除变量
💞1.7 显式报错
严格模式下,对一个使用getter方法读取的属性进行赋值,会报错。
严格模式下,对禁止扩展的对象添加新属性,会报错。
严格模式下,删除一个不可删除的属性,会报错。
💞1.8 重名错误
💞1.9 禁止八进制表示法
💞1.10 arguments对象的限制
💞1.11 函数必须声明在顶层
💞1.12 保留字
为了向将来Javascript的新版本过渡,严格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。
使用这些词作为变量名将会报错。
📧2 值在各种场景的转换规则
📧3 错误类型
ECMA-262规范指出了7种错误类型。当不同的错误条件发生时,这些类型在JavaScript引擎中都有用到,当然我们也可以手动创建它们。
Error
所有错误的基本类型。实际上引擎从来不会抛出该类型的错误。
EvalError
通过eval()函数执行代码发生错误时抛出。
RangError
一个数字超出他的边界时抛出,例如:试图创建一个长度为-20的数组( new Array(-20) )。该错误在正常代码执行中非常罕见。
ReferenceError
期望的对象不存在时抛出,例如:试图在一个null对象引用上调用一个函数。
SyntaxError
给eval()函数传递的代码中有语法错误时抛出。
TypeError
变量不是期望的类型时抛出,例如:new 10或者”prop” in true。
URIError
给encodeURI()、encodeURICommonent()、decodeURI()或者decodeURIComponent()等函数传递个是非法的URI字符串时抛出。
📧4 空值合并运算符 ‘??’
空值合并运算符 ?? 提供了一种简短的语法,用来获取列表中第一个“已定义”的变量(译注:即值不是 null 或 undefined 的变量)。
a ?? b 的结果是:
a,如果 a 不是 null 或 undefined,
b,其他情况。
所以,x = a ?? b 是下面这个表达式的简写:
下面是一个更长一点的例子。
假设,我们有一个用户,变量 firstName、lastName 和 nickName 分别对应用户的名字、姓氏和昵称。如果用户决定不输入任何值,那么这些变量都可能是未定义的。
我们想要显示用户的名称:显示这三个变量中的一个,如果都没有设置值,则显示 “Anonymous”。
让我们使用 ?? 运算符选择第一个已定义的变量:
💞4.1 与 || 比较
或运算符 || 可以与 ?? 运算符以同样的方式使用。正如 上一章 所讲的,我们可以用 || 替换上面示例中的 ??,也可以获得相同的结果。
重要的区别是:
|| 返回第一个 真 值。
?? 返回第一个 已定义的 值。
当我们想将 null/undefined 与 0 区别对待时,这个区别至关重要。
例如,考虑下面这种情况:
alert(height || 100); // 100
alert(height ?? 100); // 0
在这个例子中,height || 100 将值为 0 的 height 视为未设置的(unset),与 null、undefined 以及任何其他假(falsy)值同等对待。因此得到的结果是 100。
height ?? 100 仅当 height 确实是 null 或 undefined 时才返回 100。因此,alert 按原样显示了 height 值 0。
哪种行为更好取决于特定的使用场景。当高度 0 为有效值时,?? 运算符更适合。
💞4.2 优先级
// 重要:使用括号
let area = (height ?? 100) * (width ?? 50);
alert(area); // 5000
可以明确地使用括号来解决这个问题:
💞4.3 注意:
这两个操作符在进行比较时则要遵循下列规则。
📧6 CONSOLE 控制台输入
Console对象提供浏览器控制台的接入,不同浏览器是不一样的,这里介绍普遍存在的
💞6.1 Console.assert()
💞6.2 Console.clear()
💞6.3 Console.count()
可以带一个参数
💞6.4 Console.countReset()
💞6.5 Console.debug()
💞6.6 Console.dir()
💞6.7 Console.dirxml()
💞6.8 打印信息
%c 定义打印样式 这里的样式应该是按照,css来写的
💞6.9 打印树状结构
Console.group()
打印树状结构,配合groupCollapsed以及groupEnd方法;
Console.groupCollapsed()
同Console.group(),但是默认是折叠的
Console.groupEnd()
结束当前Tree
💞6.10 Console.table()
💞6.11 定时器
💞6.12 Console.trace()
💞6.13 占位符
这里的 %d(还有%i) 代表整数,它还支持字符串(%s)、浮点数(%f)和对象(%o)。
语法是:console.log("%c内容",样式)
控制台里就能看到如下炫酷的效果:
有点意思吧,不过这个效果是拿来做试验的,略显招摇,没有实际用途,如果你想自定义输出的字体,改个字号和颜色就好。
原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/79472.html