js手写算法原理 , 深拷贝函数, 拍平数组 , 数组去重 , 手写new , 实现 myInstanceOf , 柯里化函数

一,深拷贝函数

// 简单版本
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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值