一,深拷贝函数
// 简单版本
function deepClone1(obj) {
return JSON.parse(JSON.stringify(obj));
}
// 面试版本
// function deepClone(obj) {
// if(typeof obj !== 'object' && obj == null){
// return obj;
// }
// let copy = {}
// if(obj.Constructor === Array){
// copy = []
// }
// for(let key in obj){
// if(obj.hasOwnProperty(key)){
// copy[key] = deepClone(obj[key])
// }
// }
// }
function deepClone(obj = {}){
if(typeof obj !== 'object' && obj == null){
return obj;
}
let result
if(obj instanceof Array){
result = []
}else{
result = {}
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
result[key] = deepClone(obj[key]);
}
}
return result;
}
obj = {
name:'kunyuan',
age:15,
da:{
name:'45'
}
};
let newObj = deepClone(obj);
newObj.name = 'laj';
newObj.da.name = 'aaaaaaaa'
console.log(obj);
console.log(newObj);
二,拍平数组
const arr = [1, [2, 3, [4, [[5]]]]]
console.log(arr.flat(1));
console.log(arr.flat(2));
console.log(arr.flat(3));
console.log(arr.flat(4));
// depth<=0时,返回的数组和原数组维数一样(注意只是维数一样,空位情况见第3点)
console.log("depth<=0时,返回的数组和原数组维数一样(注意只是维数一样,空位情况见第3点)");
console.log(arr.flat(0));
console.log([].concat(...arr));
// 自己实现一个flat扁平化数组
function myflat(arr){
while(arr.some(item=>Array.isArray(item))){
arr = [].concat(...arr)
}
return arr;
}
console.log("我的实现");
console.log(myflat(arr));
// 重写原型上的方法
Array.prototype.newflat = function(n=1){
let arr = this;
while(n && this.some(item=>Array.isArray(item))){
arr = [].concat(...arr);
n--;
}
return arr;
}
console.log("重写原型上的方法");
console.log([1, 2, [3, 4, [5, [6, [7]]]]].newflat(5))
// 使用reduce方法拍平数组
function FlatReduce(arr){
return arr.reduce((pre,cur) => {
return pre.concat(Array.isArray(cur)?FlatReduce(cur):cur)
},[])
}
三,数组去重
var array = [1, 2, 1, 1, '1'];
// Array.from去重
function uniques(array){
return Array.from(new Set(array));
}
// 简化
function SampleUniques(array){
return [...new Set(array)]
}
console.log(uniques(array));
// 也可以使用es5中的indexOf方法
function es5Uniques(array){
let res = array.filter(function(item,index,array){
return array.indexOf(item) === index;
})
return res;
}
console.log("es5去重");
console.log(es5Uniques(array));
四,手写new
function mynew(func, ...args) {
let obj = {};
obj.__proto__ = func.prototype;
let result = func.apply(obj, args);
return result instanceof Object ? result : obj;
}
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
console.log(this.name + ' ' + this.age);
}
let p = mynew(Person,"邬坤源",12);
console.log(p);
p.say();
五,实现 myInstanceOf
其实 instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。
因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。
function myInstanceOf(left,right) {
let leftValue = left.__proto__;
let rightValue = right.prototype;;
while(true){
if(leftValue == null){
return false;
}
if(leftValue == rightValue){
return true;
}
leftValue = leftValue.__proto__;
}
}
console.log(myInstanceOf(1,Number));
六,柯里化函数
// 第一种:固定传入参数,参数够了才执行
/** * 实现要点:柯里化函数接收到足够参数后,就会执行原函数,那么我们如何去确定何时达到足够的参数 呢?
* * 柯里化函数需要记住你已经给过他的参数,如果没给的话,则默认为一个空数组。
* * 接下来每次调用的时候,需要检查参数是否给够,如果够了,则执行fn,
* 没有的话则返回一个新的 curry 函数,将现有的参数塞给他。 **/
// 待柯里化处理的函数
let sum = (a, b, c, d) => { return a + b + c + d }
// 柯里化函数,返回一个被处理过的函数
let curry = (fn,...args) => { // arr 记录已有参数
return args.length >= fn.length ? fn(...args) : (...arr)=> curry(fn,...args.concat(...arr))
}
var sumPlus = curry(sum)
console.log(sumPlus(1)(2)(3)(4));
console.log(sumPlus(1, 2)(3)(4));
console.log(sumPlus(1, 2, 3)(4));
七,ObjectDefineProperty实现双向数据绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" value="" name="txt" id="txt">
<p id="Show_text"></p>
</div>
<script>
var obj = {};
Object.defineProperty(obj, 'value', {
get: function () {
return obj;
},
set: function (newValue) {
document.getElementById('txt').value = newValue
document.getElementById('Show_text').innerHTML = newValue
},
})
document.addEventListener('keyup', function (e) {
obj.value = e.target.value
})
</script>
</body>
</html>