JS常见大坑
- 原型链
- typeof(null)
- this指向懵逼
- 构造函数错误调用,非new调用
- promise
- 布尔值和类型转换
- "" == 0
- "", {}, [], null, undefined, NaN
- [0] == false, Boolean([0]), [''], ['0'], [null], [undefined]
- var b = 10 + 20 + 'abc' + 'cd'
- console.log(false == '0');
- console.log(null == undefined);
- console.log(" trn" == 0);
- console.log('' == 0);
- Number和parseInt
- Number(false) 0
- Number(true) 1
- Number(undefined) NaN
- Number(null) 0
- Number("5.5 ") 5.5
- Number("56 ") 56
- Number("5.6.7 ") NaN
- Number(new Object()) NaN
- Number(100) 100
- 数字精度
- Math.pow(2,53) +1 === Math.pow(2,53) // true
- 0.1+0.2!=0.3和9999999999999999 == 10000000000000000;
- 字符串
- 3..toString;
- replace 只替换一个
- 默认全局声明
- var 变量提升
- 函数作用域
- 分号问题
- es6
- 运行时支持问题
- Chrome旧版本与严格模式限制
- node旧版本不支持
- babel is not es6
- var let = 1
- let 块级作用域、临时死区、不存在变量提升、不允许重复声明
- 箭头函数返回字面量的object
- 箭头函数不能作为构造函数
- 运行时支持问题
- lodash & angular
- 副作用函数,和非副作用的函数
- 字符串解析
- isObject 不一样逻辑
- Date类使用的时间戳和unix的差别
原型链¶
typeof(null)¶
typeof(null) === 'Object' // true!
错误的判断对象
var a = {} if (typeof a === 'Object') { // ... }
所以使用typeof判断对象的正确使用方法
var a = {} if (a != null && (typeof a === 'object' || typeof a === 'function')) { // 注意函数也是object... // ... }
忽略原型链属性¶
let sumUp = {} let content = "providing constructor for your classes. A class contains constructors that are invoked to create objects from the class blueprint" for (let word of content.split(' ')) { if (!sumUp[word]) { sumUp[word] = 1 } else { sumUp[word] += 1 } } console.log(sumUp)
{ providing: 1, constructor: 'function Object() { [native code] }1', for: 1, your: 1, 'classes.': 1, A: 1, class: 2, contains: 1, constructors: 1, that: 1, are: 1, invoked: 1, to: 1, create: 1, objects: 1, from: 1, the: 1, blueprint: 1 }
let sumUp = Object.create(null)
for…in 操作¶
运维开发写python写的比较多。但是在python中的for in 和js中的for in 不是同一个含义。
for…in循环定义
for…in 循环只遍历可枚举属性。像 Array和 Object使用内置构造函数所创建的对象都会继承自Object.prototype和String.prototype的不可枚举属性,例如 String 的 indexOf() 方法或 Object的toString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。
可枚举属性
可枚举属性是指那些内部 “可枚举” 标志设置为 true 的属性 默认标记为true情况: - 字面量方式定义的属性 - 直接的赋值的属性
Example: 忽视原型链属性导致的错误¶
let arr = [1, 2, 3, 4, 5] for (let x in arr) { let ele = arr[x] console.log(ele) } // 1 // 2 // 3 // 4 // 5
Array.prototype.test = function () {} let arr = [1, 2, 3, 4, 5] for (let x in arr) { let ele = arr[x] console.log(ele) } // 1 // 2 // 3 // 4 // 5 // test <-- wrong!
数组遍历推荐使用 for…of…
语法
for (variable of iterable) { //statements }
Example: for…of用法¶
可以理解为真正的js类似python的for each循环
Array.prototype.vlaue = 'test' let arr = [1, 2, 3, 4, 5] for (let x of arr) { console.log(x) }
实力懵逼的原型链关系¶
typeof null // Object ???
Object instanceof Object // true
Function instanceof Object // true ???
Object instanceof Function // true ???
Function instanceof Function // true ???
Function.prototype instanceof Object // true
Function.prototype instanceof Function // ture ???
Object.__proto__.__proto__.constructor == Object // true ???
Function.constructor === Function // true ???
还是判断一个变量是不是对象,使用instanceof