1. js数据类型及判断
内置数据类型:null、undefined、boolean、number、string、object(function、array、date等)、symbol。
-
typeof判断类型
typeof null // 'object' const foo = () => 1 typeof foo // 'function' const foo = {} typeof foo // 'object' const foo = [] typeof foo // 'object' const foo = new Date() typeof foo // 'object' const foo = Symbol('foo') typeof foo // 'symbol'
typeof可以准确判断除null以外的基础数据类型,但是不能精确判断object具体类型。
-
instanceof判断类型
a instanceof b,a是否为b的实例,即a的原型链上是否存在b的构造函数function Person(name) { this.name = name } const p = new Person('p') p instanceof Person // true p.__proto__.__proto__ === object.prototype
p是Person构造出来的实例对象,顺着p的原型链也能找到Object的构造函数。
5 instanceof Number // false new Number(5) instanceof Number // true
上面的5是基本类型,并不是Number构造函数构造出来的实例对象。
模拟实现:
const instanceofMy = (a, b) => { if (typeof a !== 'object') { return false } while (true) { if (a === null) { return false } if (b.prototype === a.__proto__) { return true } a = a.__proto__ } }
-
constructor和Object.prototype.toString判断类型(万能方法)
console.log(Object.prototype.toString.call(1)) // [object Number] // [object Undefined] // [object Object] // [object Array] // [object Function] // [object Null] // [object String] // [object Boolean] // [object Symbol]
slice(8, -1)可以得到精确的类型判断。
var foo = [] foo.constructor // f Array() { [native code] } ...
但是对于undefined和null,读取constructor属性则会报错。
2. js数据类型及判断
console.log({} + true)
// [object object]true
在+运算符两侧,如果存在复杂数据类型,涉及到对象类型转基本类型。在转换时,会调用该对象上的valueOf或toString方法,具体调用是ES规范决定,取决于内置的toPrimitive的调用结果。主观上来说,如果倾向于转为number类型,就优先调用valueOf,反之则调用toString。另一种理解是先调用valueOf,再调用toString。
3. js函数传参
let foo = 1
const bar = value => {
value = 2
console.log(value)
}
bar(foo)
console.log(foo)
// 2
// 1
函数参数为基本类型时,函数内复制了一份参数值,任何操作都不会影响原参数。
let foo = {a: 1}
const bar = value => {
value.a = 2
console.log(value)
}
bar(foo)
console.log(foo)
// 2
// {a: 2}
函数参数是引用类型时,在函数内修改某个属性值时,会对原参数进行修改。
let foo = {a: 1}
const bar = value => {
value = 2
console.log(value)
}
bar(foo)
console.log(foo)
// 2
// {a: 1}
函数参数是引用类型时,如果直接修改这个值得引用地址,相当于在函数内新建了一个引用,不会影响原参数。
4. 读取不到属性问题
- 通过&&短路进行可访问性试探。
- 通过||设置保底默认值。
- 设置try…catch。
- 使用lodash get方法。
get方法简易实现:
const get = path => obj =>
path.reduce((xs, x) =>
(xs && xs[x]) ? xs[x] : null, obj)