ES6语法篇(1)
文章目录
- 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]);// 不相等 完成了深拷贝了