小知识积累

1、使用JSON.parse(JSON.stringify()) 深拷贝时会出现的问题
      var obj = {
        a: "zs",
        b: undefined,
        c: Symbol("score"),
        d: null,
        e: function () {
          console.log("show");
        },
        f: /a/
      };

      console.log(JSON.parse(JSON.stringify(obj)));

在这里插入图片描述

      const obj1 = {
        name: "obj1",
      };
      
      const obj2 = {
        name: "obj2",
        relative: obj1,
      };
      
      obj1.relative = obj2;
      console.log(JSON.parse(JSON.stringify(obj2)));

在这里插入图片描述

由上可知:
1、当属性值为undefined、函数、symbol 、正则表达式时该属性会丢失
2、拷贝循环引用对象时会报错

2、useEffect、useLayoutEffect执行顺序
const Child = () => {
  useEffect(() => {
    console.log(1);
  }, []);
  useLayoutEffect(() => {
    console.log(2);
  }, []);
  return null;
};

const Parent = () => {
  useEffect(() => {
    console.log(3);
  }, []);
  useLayoutEffect(() => {
    console.log(4);
  }, []);
  return <Child/>;
};

输出结果:
在这里插入图片描述
解释:react中会先执行子组件、useLayoutEffect是同步、useEffect是异步, 所以最开始输出子组件的同步任务2,然后把子组件的异步任务回调添加到异步队列,然后回到父组件相同执行。

3、对象遍历顺序问题
      var obj = {
        name: "zs",
        age: 2,
        1: "a",
        0: "c",
      };
      
      console.log(obj);

      for (var k in obj) {
        console.log(k);
      }

在这里插入图片描述

由上可知无论是直接输出obj,还是遍历obj,都和我们定义的obj属性顺序不同。所以普通对象是无序的。

4、Map的相关问题:
      var value = new Map();
      value.set(2, "a");
      value.set(0, "b");
      value.set(1, "c");
      value.set(1, "w");
      value.set(null, "d");
      value.set(undefined, "e");
      value.set(undefined, "w");

      console.log(value.get(undefined))
      console.log(value.get(null))
      console.log(value);

在这里插入图片描述

由上可知:
1、null和undefined可以作为Map对象的key
2、相同key后设置的会覆盖之前的(包括null、undefined)
3、Map对象的key是有序的,和你插入顺序有关

5、深拷贝循环引用问题:
	// 使用weakmap解决循环引用
	// 优点:
	// 1 .WeakMap来记录对象是否被克隆,主要考虑一下三点。
	//  2 .WeakMap对象是key=>value形式,不会重复记录
	//  3 .WeakMap是弱引用,如果不在使用,空间会直接释放

     function deepCopy (obj, hash= new WeakMap()) {
       // 不是对象(普通值类型/function),null,undefined,正则,Date都会直接返回
       if(obj == null || typeof obj != 'object') {
        return obj
       }
       if(obj instanceof RegExp ) {
          return new RegExp(obj)
       }
       if( obj instanceof Date) {
        return new Date(obj)

       }

       // 判断是否循环引用的(判断属性是不是存在了)
       if(hash.get(obj)) return hash.get(obj)

       let cloneObj = new obj.constructor()

      // 存obj
        hash.set(obj, cloneObj)

       for(let key in obj) {
        // in 循环会遍历原型链的,所以需要判断是否是当前对象的属性
        if(obj.hasOwnProperty(key)) {
          cloneObj[key] = deepCopy(obj[key], hash)
        }
       }

       return cloneObj
     }
6、vue判断数据有没有变化源码
function hasChanged(x, y) {
  if (x === y) {
    return x === 0 && 1 / x !== 1 / y;
  } else {
    return x === x || y === y;
  }
}

疑惑:已经判断了x === y,为什么else里还要判断?

NaN === NaN //false

因为NaN的缘故,如果x为NaN,又给它赋值为NaN,其实是没有变化的, 所以在else中判断x === x就可以知道它是NaN这种情况

疑惑:为什么判断 x === 0 && 1 / x !== 1 / y ?

+0 === -0 //true
1/+0 //Infinity
1/-0 //-Infinity
7、闭包的优缺点

优点:
1、可以读取另一个函数作用域中的变量
2、让这些变量始终保存在内存中,便于复用
3、封装对象的私有属性和私有方法

缺点:
使用不当容易造成内存泄漏

如何清除:

function parent(){
	var a = 1;
	return function child(){
		console.log(a++)
	}
}

var fn = parent()
fn()

fn = null//清除闭包
8、不改变源码的情况下改变内部变量
      function o() {
        var obj = {
          name: "zs",
          age: 11,
        };
        return {
          getVal: function (key) {
            return obj[key];
          },
        };
      }

      Object.defineProperty(Object.prototype, "a", {
        get() {
          return this;
        },
      });
      
      var obj2 = o().getVal("a")//获得原始obj
      obj2.x = 1

9、判断函数是不是被new调用
  function User() {
      if (this instanceof User) {
          console.log('new调用')
      } else {
          console.log('函数调用')
      }
  }
  
  var p = new User()//new 调用
  User()//函数调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值