JS
1.数据类型
基本数据类型:Undefined,Null,Boolean,Number,String,Symbol
引用数据类型:Array,Function,Object,Date
注意 Undefined 和 Null 的区别:
Undefined 表示已声明未赋值
Null 表示一个对象不存在
2.数据类型判断
> typeof
注意:typeof 在判断 null 是返回的是 Object,
js使用二进制存储,对象标记位是000, null 全是 0 ,所以typeof null 返回 Object
typeof 判断 数组 Date 都返回 Object 无法具体判断出是哪种对象
> instanceof
注意:instanceof 只能用于判断对象是否属于某个构造函数的实例,无法判断基本数据类型
> Object.prototype.toString.call ()
在实际开发中,可根据具体需求选择合适的方法来判断数据类型。
如果只是简单区分基本数据类型(除了 null 的不准确情况), typeof 可能就够用了;
如果要准确判断对象类型或处理一些特殊情况,可能就需要用到 instanceof 或
Object.prototype.toString.call()方法。
数组独有的判断方法 Array.isArray( arr )
3.原型和原型链
原型: 函数都有一个 prototype 属性,它指向一个对象,这个对象称之为原型,也叫原型对象
作用: 1.存放一些属性和方法;2.可以实现继承
原型链:对象都有一个 __proto__(隐式原型) 属性指向它的原型对象,
原型对象也是对象也有自己的一个 __proto__ 指向原型对象的原型对象,
这样一层层形成的链式结构叫做原型链,直到最后找不到则返回 null。
构造函数都是 Function 的实例,Function 的隐式原型和显式原型是同一个。
4.深浅拷贝
浅拷贝:
1. 扩展运算符( ... )
let obj1 = { name: 'Alice', age: 25 }
let obj2 = { ...obj1 }
2. Object.assign( )
let obj1 = { name: 'Alice', age: 25 }
let obj2 = Object.assign( { } , obj1 )
3. 数组拷贝 slice( )
let arr = [1, 2, 3];
let arr2 = arr.slice( );
// [1, 2, 3]
深拷贝:
1. JSON.parse(JSON.stringify())
有一定局限性
- 不能处理函数、Symbol、undefined(属性丢失)
- 会丢失Date对象的时间信息(转为字符串)
- RegExp 对象转为空对象
2.递归实现
function deepClone(obj, hash = new WeakMap()) {
// 基本类型直接返回
if (obj === null || typeof obj !== 'object') return obj;
// 处理Date
if (obj instanceof Date) return new Date(obj);
// 处理RegExp
if (obj instanceof RegExp) return new RegExp(obj);
// 处理函数(直接返回引用)
if (typeof obj === 'function') return obj;
// 处理循环引用
if (hash.has(obj)) return hash.get(obj);
// 处理Set
if (obj instanceof Set) {
const cloneSet = new Set();
hash.set(obj, cloneSet);
obj.forEach(value => cloneSet.add(deepClone(value, hash)));
return cloneSet;
}
// 处理Map
if (obj instanceof Map) {
const cloneMap = new Map();
hash.set(obj, cloneMap);
obj.forEach((value, key) => cloneMap.set(key, deepClone(value, hash)));
return cloneMap;
}
// 处理数组或普通对象
const cloneObj = Array.isArray(obj) ? [] : Object.create(Object.getPrototypeOf(obj));
hash.set(obj, cloneObj);
// 复制Symbol属性
const symKeys = Object.getOwnPropertySymbols(obj);
symKeys.forEach(symKey => {
cloneObj[symKey] = deepClone(obj[symKey], hash);
});
// 复制普通属性
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key], hash);
}
}
return cloneObj;
}
Vue
1.谈谈你对SPA的理解