常见手写
深拷贝
js
/**
* 判断是否是基本数据类型
* @param value
*/
function isPrimitive(value) {
return (
typeof value === "string" ||
typeof value === "number" ||
typeof value === "symbol" ||
typeof value === "boolean"
);
}
/**
* 判断是否是一个js对象
* @param value
*/
function isObject(value) {
return Object.prototype.toString.call(value) === "[object Object]";
}
/**
* 深拷贝一个值
* @param value
*/
function cloneDeep(value) {
// 记录被拷贝的值,避免循环引用的出现
let memo = {};
function baseClone(value) {
let res;
// 如果是基本数据类型,则直接返回
if (isPrimitive(value)) {
return value;
// 如果是引用数据类型,我们浅拷贝一个新值来代替原来的值
} else if (Array.isArray(value)) {
res = [...value];
} else if (isObject(value)) {
res = { ...value };
}
// 检测我们浅拷贝的这个对象的属性值有没有是引用数据类型。如果是,则递归拷贝
Reflect.ownKeys(res).forEach((key) => {
if (typeof res[key] === "object" && res[key] !== null) {
//此处我们用memo来记录已经被拷贝过的引用地址。以此来解决循环引用的问题
if (memo[res[key]]) {
res[key] = memo[res[key]];
} else {
memo[res[key]] = res[key];
res[key] = baseClone(res[key]);
}
}
});
return res;
}
return baseClone(value);
}
手写 instanceof
具体使用
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。 判断一个实例是否是其父类或者祖先类型的实例。
js
var simpleStr = "This is a simple string";
var myString = new String();
var newStr = new String("String created with constructor");
var myDate = new Date();
var myObj = {};
var myNonObj = Object.create(null);
simpleStr instanceof String; // 返回 false,非对象实例,因此返回 false
myString instanceof String; // 返回 true
newStr instanceof String; // 返回 true
myString instanceof Object; // 返回 true
myObj instanceof Object; // 返回 true,尽管原型没有定义
({}) instanceof Object; // 返回 true,同上
myNonObj instanceof Object; // 返回 false,一种创建非 Object 实例的对象的方法
myString instanceof Date; //返回 false
myDate instanceof Date; // 返回 true
myDate instanceof Object; // 返回 true
myDate instanceof String; // 返回 false
具体实现
js
function instanceOf(target, type) {
while (target) {
if (Object.getPrototypeOf(target) === type.prototype) {
return true;
}
target = Object.getPrototypeOf(target);
}
return false;
}
数组的 map 方法
实现
js
Array.prototype.map = function (fn, value) {
let res = [];
value = value || window;
let arr = this;
for (let i in arr) {
if (arr.hasOwnProperty(i)) {
res.push(fn.call(value, arr[i], i, arr));
}
}
return res;
};
Array.prototype.myMap = function (fn, thisValue) {
var res = [];
thisValue = thisValue || [];
this.reduce(function (pre, cur, index, arr) {
return res.push(fn.call(thisValue, cur, index, arr));
}, []);
return res;
};
手写 reduce
实现
js
Array.prototype.myReduce = function (cb, initValue) {
let _arr = this;
let num = initValue == undefined ? _arr[0] : initValue;
let i = initValue == undefined ? 1 : 0;
for (i; i < _arr.length; i++) {
num = cb(num, _arr[i], i, _arr);
}
return num;
};
let arr = [1, 2, 3, 4];
arr.myReduce(function (num, item, index, arr) {
return num + item;
});