ES6语法之--对象的拓展,深拷贝和浅拷贝

ES6语法篇(1)


日常更新ES6语法。

对象的拓展


    // key 和 value的 名字是一样的,可以简写 
    let name = "毛毛";
    const obj = { name };

    // TODO  属性名表达式
    // 变量的值作为key
    let s = 'mao';
    const o1 = {
      [s]: '毛毛'
    }
    console.log(o1);
    s = 'aa';
    console.log(o1);

    // 对象方法的简写
    let o2 = {
      // 方法尽量不要使用箭头函数
      // 除非是为了this的指向就是定义时的作用域
      study() {
        console.log('我是简写');
      }
    };
    o2.study();

    // == 和 === 的区别
    // == 只会判断值是否相等
    // === 还会判断类型是否相等 严格相等
    console.log(2 == '2'); // true
    console.log(2 === '2'); // false
    // 使用 Object.js(变量1,变量2) 进行判断变量是否相等,和 === 一样
    console.log(Object.is(2, '2'));// false
    // Object.is() 还可以判断 NaN是否相等 ===则不行
    console.log(NaN == NaN, NaN === NaN, Object.is(NaN, NaN));
    console.log(Object.is(+0, -0)); // false
    // 对象比较的是内存地址
    console.log({} == {}, {} === {}, Object.is({}, {})); // false

    let x = {
      a: 3,
      b: 4
    }
    // 对象的拓展
    let y = { ...x };
    console.log(y, x); // 属性和值都相等

    // 也可以使用 Object.assign() 进行对象属性的合并
    // 参数一:目标对象,参数二:源对象
    // 将源对象的属性合并到目标对象上,源对象不变
    let z = {};
    // 如果属性相等则会覆盖,不同属性则合并到目标对象上
    Object.assign(z, x);
    console.log(z, x);
    // 可以使用 in运算符,判断某个属性是否在对象上
    // for(let i in x) console.log(i); // 遍历对象的属性
    console.log('a' in x, 'aa' in x); // true false

    // in 运算符 还可以判断数组下标位置元素是否存在
    let arr = [1, 2, 3, 4];

    console.log(3 in arr, 4 in arr);// TODO 判断的是下标

    // Object.keys(对象) 拿到这个对象所有的键组成的数组
    Object.keys(x).forEach(key => console.log(key));

    // Object.getOwnPropertyNames(对象) 拿到对象的自己身上的属性
    Object.getOwnPropertyNames(x).forEach(key=>console.log(key))

    // Reflect.ownKeys(对象) 拿到对象身上的属性名
    Reflect.ownKeys(x).forEach(key=>console.log(key))

深拷贝和浅拷贝


// 深拷贝和浅拷贝
// 如何把一个对象复制给另一个对象
const obj = {
  name: "毛毛",
  age: 21,
  gender: "男",
  friend: {
    name: 'zhang'
  }
}; //?

// 方法一: Object.assign()
const tar1 = {};
Object.assign(tar1, obj);//?
// 修改目标对象的 friend属性
tar1.friend.name = 'ttt';//?
console.log(obj.friend);//可以看见源对象的friend属性也发生了改变
// 所以 assign方法只使用于浅拷贝
// 对于引用数据类型,直接复制了地址
console.log(obj.friend === tar1.friend);

// TODO  当然 JSON 不支持方法的拷贝
// 可以使用 JSON.stringify 和 JSON.parse 两个方法完成深拷贝
let tar2 = JSON.stringify(obj);//?
tar2 = JSON.parse(tar2);//?

tar2.friend.name = '222';
console.log(tar2.friend, obj.friend);

// 这两个属性指向的地址不同了
console.log(tar2.friend === obj.friend);



// TODO  实现一个深拷贝函数 不包含函数
/**
 *检查数据类型的函数
 *
 * @param {*} data
 * @returns 返回数据的类型
 */
const checkType = data => {
  // type判断数据类型 只能判断基本数据类型

  // 所以我们一般通过toString转换以后再来判断数据类型
  // console.log(Object.prototype.toString.call(data));// [object String]
  // 转换以后进行截取
  return Object.prototype.toString.call(data).slice(8, -1);
}
checkType(1);//?
/**
 *
 * 进行深拷贝的函数
 * @param {*} target 源对象,用来进行拷贝
 * @returns 返回拷贝完成的对象
 */
const deepClone = target => {
  // 判断对象类型
  const targetType = checkType(target);
  // 返回拷贝后的对象
  let result;
  if (targetType === "Object") {
    // 对象类型
    result = {};
  } else if (targetType === "Array") {
    // 数组类型
    result = [];
  } else {
    // 基本数据类型 直接返回即可
    return target;
  }
  // 递归拷贝
  for (let i in target) {
    // 对象和数组 都使用
    let value = target[i];
    let valueType = checkType(value);
    if (valueType === "Object" || valueType === "Array") {
      result[i] = deepClone(value);
    }else{
      result[i] = value;
    }
  }
  // 返回深拷贝完成后的对象
  return result;
}
const source = [1,2,{name:"毛"}];//?
const arr = deepClone(source);//?
console.log(arr[2] === source[2]);// 不相等 完成了深拷贝了
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤雨东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值