// Uncaught TypeError: (intermediate value)(...) is not a function
var a = function(x) { console.log(x) }
(function() {
console.log('hello')
})()
// hello
var a = function(x) { console.log(x) };
(function() {
console.log('hello')
})()
或者是这样的时候:
// [4, 9]
var a = [1, [2, 3]]
[3, 2, 1].map(function(num) {
return num * num;
})
// [9, 4, 1]
var a = [1, [2, 3]];
[3, 2, 1].map(function(num) {
return num * num;
})
typeof arguments.length // number
Object.prototype.toString.call(arguments) // [object Arguments]
arguments.slice(0, 1) // TypeError: arguments.slice is not a function
var args = Array.prototype.slice.apply(arguments)
Object.prototype.toString.call(arguments) // [object Array]
args.slice(0, 1) // no error
ES6解决方案
[...arguments]
eval
function test() {
var x = 2, y = 4;
// 直接调用 使用函数内作用域的x, y
console.log(eval("x + y"))
var geval = eval;
// 不是直接调用,使用全局的scope 报错 ReferenceError `x` is undefined
console.log(geval("x + y"))
}
在本文中,笔者将会为大家介绍一些JavaScript在发展过程中的一些重要的设计缺陷,这些缺陷往往使得JS新手在开发过程中容易犯错。
过时的功能
有状态的 RegExp 函数
stop talking show me the code
按照大家对于正则的理解,上面的返回结果应该是
true true
先来看看在控制台上运行以上代码的结果:
最后代码运行的结果和我们的预期结果不一致,导致这样的结果是因为在JS的RegExp中存在一个lastIndex属性。
只有正则表达式使用了表示全局检索的 "g" 标志时,该属性才会起作用。此时应用下面的规则:
复杂的类型系统
隐式转换之运算
不管是JS新手还是很有经验的老司机,JS的类型转换可以说是这门语言的一个让人“又爱又恨”的地方了,让我们先来几个例子看看
在下面公布代码运行结果之前,大家可以先自己给出一份结果,然后验证一下
隐式转换之等于
先看代码:
同上,在公布结果之前,大家可以先给出自己的结果,然后验证一下
是不是感受到了,JS的隐式转换的”魅力“所在,而且在社区,大家还总结了一张 JavaScript-Equality-Table 高清地址
在ES6中,可以使用Object.is来解决这个问题
受Java的历史影响
Date的问题
因为JavaScript的Date对象是基于Java1.0而参考实现的,随着Java的版本的迭代,一些“有问题”的方法逐渐被抛弃,但是JS却还保留着...
大家粗略一眼看去,可能认为的结果如下:
运行代码结果如下:
第二个
getDate()
返回的值不是2016,而是116(通过2016-1900
)得出,具体为什么要减去1900,大家可以查阅相关资料。Auto-Semicolon-Insertion (ASI) 自动分号插入
很多的语言都支持不写分号,比如:Swift Python Golang等,但是在JS中你不写分号,有时候会产生一些问题
比如 在
函数return
的时候比如 在
另起一行写一个IIFE的时候
或者是这样的时候:
有兴趣的同学 点这里了解更多
解决办法
在
([+-/
开始的一行之间加一个;
举个例子作用域
函数作用域
解决方案 使用块作用域(let/const)
变量提升
熟悉JS特性的同学肯定知道上面两段代码是等价的
解决方案
Temporay Dear Zone (暂死区)
对于TDZ不了解的同学可以参考这篇文章
“关键字”的误导
const
看起来,const关键字是表示来定义一个常量的,实际上不是这样
Function.prototype
API设计的问题
NaN
数组初始化
Array-like Objects
ES6解决方案
eval
具体的原因 有兴趣的同学可以查看eval规范
大概意思就是如果直接调用就绑定当前上下文执行,否则就是全局上下文执行
结束语
希望大家以后在开发的过程中,能够对上面的一些case能够有一定的印象,能够在开发过充中避免“踩坑”,如果还有其他你觉得也属于JS的设计缺陷的,欢迎一起讨论,有错误的欢迎指出,谢谢!