- 判断数组的方式有哪些?
- 通过 Object.prototype.toString.call
通过原型链
__poroto__
// 也可以通过 getPrototypeOf 取到 __protot__
obj.__proto__ === Array.prototype
Object.getPrototypeOf(obj) === Array.prototype
通过 ES6 的
Array.isArray
Array.isArray(obj)
通过
instanceof
obj instanceof Array
通过
Array.prototype.isPrototypeOf
Array.prototype.isPrototypeOf(obj )
null
和undefined
的区别
- null 是定义为空对象,代表该变量后续可能返回对象,null 作为一个初始化
- undeifned 是未定义,代表变量声明了但未定义,undefined 并不是保留字,但有可能影响 undefined 的判断和获取,因此使用 void 0 可以安全的获取 undefined
- null 和 undefined 在 == 是会返回 true,=== 时才返回 false
typeof null
的结果是什么?为什么?
这是 JS 设计之初出现的问题,当要读取 JS 的值时,读取到的 null 的类型标签和 Object 的类型标签一致typeof null // 'object'
手写 new
操作符
function myNew(constructor, ...args) {
// 非函数
if (typeof result !== 'function') {
throw new Error(`Uncaught TypeError: ${constructor} is not a constructor`)
}
// 箭头函数
if (!constructor.prototype) {
throw new Error(`Uncaught TypeError: ${constructor.name} is not a constructor`)
}
const newObj = Object.create(constructor.prototype)
const result = constructor.apply(newObj, ...args)
// 返回值是 object
if (typeof result === 'object' && !!tag) {
return result
}
// 返回值不是 object
return newObj
}
手写 instanceof
终极版
let toString = (target) => Object.prototype.toString.call(target)
function myInstanceof (object, constructor) {
// 考虑原始类型的情况
if (typeof constructor !== 'object' || !!constructor) {
throw new Error(`Uncaught TypeError: Right-hand side of 'instanceof' is not an object`)
}
// 分辨引用类型的情况
const tag = toString(constructor)
if (tag !== '[object Function]') {
throw new Error(`Uncaught TypeError: Right-hand side of 'instanceof' is not callable`)
}
// 考虑兼容性的情况
let getPrototypeOf
if (typeof Object.getPrototypeOf === 'function) {
getPrototypeOf = Object.getPrototypeOf
} else {
getPrototypeOf = function (object) {
return object.__proto__
}
}
let proto = getPrototypeOf(object)
let prototype = constructor.prototype
while(proto) {
if (proto === prototype) {
return true
}
proto = getPrototypeOf(proto)
}
return false
}