
section 1
Interviewer: 请介绍一下js
的数据类型~
Interviewee:
- 可以分为两种类型:
基本数据类型
和引用数据类型
; - 基本数据类型包括:数字(number)、字符串(string)、布尔值(boolean)、undefined、null;
- 引用数据类型包括:
对象(Object)
、数组(Array)
、函数(Function)、正则(RegExp)和日期(Date)等。
section 2
Interviewer: 那么基本类型和引用类型有什么区别呢~
Interviewee:
- 存储:基本类型值:保存在
栈内存中
;引用类型值:保存在堆内存中
。 - 复制:引用类型需要切断引用。
- 传递:函数执行完毕,基本类型不会改变,引用类型可能改变。详见
- 类型检测(
goto section3
)
section 3
Interviewer: 怎么判断一个数据类型呢~
Interviewee:
- 如果是基本类型,
typeof
就够用了; - 如果是引用类型,
instanceof
就够用了; - 如果判断所有的类型,需要使用
Object.prototype.toString.call
;
section 4
Interviewer: 你能够实现一个instanceof 么~
Interviewee:让我想想~~~~
Object.prototype.instanceof = function(constructor) {
return this.__proto__ === constructor.prototype;
}
section 5
Interviewer: 你能够实现一个isType 么~
Interviewee:让我想想~~~~
const TYPES = ['String', 'Number', 'Array', 'Null', 'Undefined'];
const isType = type => element => Object.prototype.toString.call(element) === `[object ${type}]`;
const Types = TYPES.reduce((prev, curr) => ({ ...prev, [`is${curr}`]: isType(curr) }), {});
Types.isArray([]); // true
// 组合
const Types = ['String', 'Number', 'Array', 'Null', 'Undefined']
.reduce((prev, curr) => ({
...prev,
[`is${curr}`]: element => Object.prototype.toString.call(element) === `[object ${curr}]`
}), {});
section 6
Interviewer: 你刚说道复制,你知道深copy和浅copy么,可以简单实现一个么?
Interviewee: 是这样的。深copy 要看使用场景
- 如果没有特殊要求,可以用
JSON.stringfy
和JSON.parse
const deepClone = element => JSON.parse(JSON.stringify(element));
-
如果使用场景复杂,考虑使用loash,
_.cloneDeep
-
以下是我实现深copy的方案(只考虑
数组
和对象
,不考虑原型链上数据)
const deepClone = (element) => {
if (!(typeof element === 'object')) return element;
if (element === null) return null;
return element instanceof Array
? element.map(item => deepClone(item))
: Object.entries(element).reduce((pre, [key, val]) => ({ ...pre, [key]: deepClone(val) }), {});
}