这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战
很久没有写文章了,刚好借更文挑战督促自己学习。最近一直忙着秋招,感觉自己对于技术的沉淀还是少了点,给自己定个小目标吧。
最近在学JS的时候的遇到了很多手写数组、对象、字符串、函数的方法,一直没有总结。想着写一篇文章总结一下,刚好可以对知识进行一个巩固。
1、Object.assign
- 定义
Oject.assign(target,...sources)用于将可枚举属性的值从一个或者多个源对象分配到目标对象,它将返回目标对象。
简单的说,就是可以将值进行一个复制,在对象的浅拷贝中常用。
比如,将对象A拷贝到对象B
const objectA = {
name: 'ObjectA',
age: 18
};
const objectB = {
name: 'ObjectB',
age: 20
};
const returnedTarget = Object.assign(objectA, objectB);
console.log(objectA); // {name: 'ObjectB', age: 20}
console.log(objectB); // {name: 'ObjectB', age: 20}
console.log(returnedTarget); // {name: 'ObjectB', age: 20}
从上面的代码中可以看出来,对象A拷贝给对象B的时候,对象A自身也发生了变化。这也就是经典的浅拷贝。
- 实现方法
由上面的用法中可以看出,主要是将源对象拷贝到目标对象上,而对象的复制不是复制基本数据类型,将值拷贝即可。
这里我们使用Object.defineProperty()在对象上定义方法。(Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。)
Object.defineProperty(Object, 'assign', {
value: function(target, ...args) {
if (target == null) {
return new TypeError('Cannot convert undefined or null to object');
}
// 统一引用数据类型
const to = Object(target);
for (let i = 0; i < args.length; i++) {
// 每一个源对象
const nextSource = args[i];
if (nextSource !== null) {
// 使用for...in和hasOwnProperty双重判断,确保只拿到本身的属性、方法
for (const nextKey in nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
// 不可枚举
enumerable: false,
// 属性值不可被修改
writable: true,
// 属性的描述符不可被改变
configurable: true,
})
1、首先明确传入对象:目标对象、源对象
2、判断目标对象是否为空
3、统一目标对象为引用数据类型
4、遍历源对象,使用for...in和hasOwnProperty双重判断,拿到本身的属性和方法,最后返回目标队形
2、Object.is
- 定义
Oject.is(target,...sources)用于判断两个值是否为同一个值。
虽然是对象方法,但是可以判断的值不仅仅是对象。
可以判断下面两个值:
-
传入的值都是
undefined -
传入的值都是
null -
传入的值都是
true或者false -
传入的值是相同的字符串
-
传入的值是相同对象(也就是引用地址相同)
-
传入的值都是数字且都是+0 或者 -0 或者NaN或者其他数字
我们可以测试一下:
let objectA = {
name: '1',
age: 12
};
let objectB = {
name: '1',
age: 12
}
let objectC = objectA
// 1
console.log(Object.is(undefined, undefined)); // true
console.log(Object.is(null, null)); // true
console.log(Object.is(true, true)); // true
console.log(Object.is(true, false)); // false
console.log(Object.is('str', 'str')); // true
// 2
console.log(Object.is(objectA, objectB)); // false
console.log(Object.is(objectA, objectC)); // true
// 3
console.log(Object.is(0, 0)); // true
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false
第一部分没什么好说的,就是寻常的判断是否相等;第二部分需要注意的是,如果两个对象的内容相等,但是引用地址不同,Object.is返回的是false. Object.is主要是为了解决第三部分的问题的。
在普通的相等符号判断中,NaN === NaN 是返回false,这就与我们想要的效果不一样了,还有 +0 和 -0 ,在我们的意识当中,+0 和 -0 应该是不相等的才对。
所以实现这个方法主要就是解决这个问题。
实现的代码贴一下:
const is = (x, y) => {
if (x === y) {
return x !== 0 || y !== 0 || 1 / x === 1 / y
} else {
return x !== x && y !== y
}
}