JS函数的神奇特性:深入剖析让代码更优雅的利器
2023-09-19 23:28:44
日常业务写的太多已经麻痹了神经,很多本该知道的知识早已抛之脑后,大家都知道在JS中函数是一等公民,但是竟然{有人|作者}连它的特性都不清楚,真是惭愧。 在日常业务开发中,通常都会在数据中给一个默认值,然后在请求后端数据后替换掉默认值,如果完全替换整个对象肯能并不是我们想要的,因为这样会直接影响到外面引用的数据源,所以我们可以先对源对象进行克隆,然后在克隆的对象中进行修改,这样就可以保证源对象不变。
那么问题又来了,克隆的方法太多了,如何选择一个适合自己的并且能时刻记住的方法呢?大家一定听说过JSON.parse(JSON.stringify(obj))这种克隆方法,也是日常开发中最常用的方法,但是这种方法有一个坑就是会丢失一些类型的数据,比如说Date、Map、Set、undefined、Function等。这是因为它在克隆的时候会将对象转成JSON字符串,然后在转换成对象,在转字符串的过程中就丢失了上述类型的数据,这时候我们可以使用结构克隆算法来克隆对象。
在ES6中提供了一个Object.assign()方法,该方法可以对源对象进行浅拷贝,它会将源对象的所有可枚举属性拷贝到目标对象,但是需要注意的是,它不会拷贝源对象的原型上的属性,所以如果源对象的属性是继承自其原型的,那么这些属性不会被拷贝到目标对象中。如果需要拷贝源对象的原型上的属性,则可以使用Object.create()方法。
结构克隆算法是一种可以对对象进行深度拷贝的算法,它会递归地克隆对象的所有属性,包括原型上的属性。这种算法通常用于克隆复杂的对象,如包含循环引用的对象。
function deepClone(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (obj instanceof Map) {
return new Map(Array.from(obj.entries()));
}
if (obj instanceof Set) {
return new Set(Array.from(obj));
}
if (obj instanceof Function) {
return obj.bind({});
}
const clonedObj = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = deepClone(obj[key]);
}
}
return clonedObj;
}
除了克隆对象,我们还可以使用函数来对对象进行操作。在JavaScript中,函数也是一等公民,这意味着函数可以像其他值一样被传递、返回和存储。这种特性使得函数非常灵活,可以用于各种不同的目的。
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
const calculate = (operation, a, b) => {
if (operation === 'add') {
return add(a, b);
} else if (operation === 'multiply') {
return multiply(a, b);
}
};
console.log(calculate('add', 1, 2)); // 3
console.log(calculate('multiply', 3, 4)); // 12
在上面的示例中,我们定义了两个函数add和multiply,这两个函数都接收两个参数并返回这两个参数的和或积。然后我们定义了一个函数calculate,该函数接收三个参数:一个操作符(operation)、两个数字(a和b)。calculate函数根据操作符调用add或multiply函数,并将结果返回。
这种使用函数来对对象进行操作的方式非常灵活,可以用于各种不同的目的。例如,我们可以使用函数来对列表中的数据进行排序、过滤和聚合。
函数式编程是一种编程范式,它强调使用函数来对数据进行操作,而不是使用命令式编程中常见的循环和条件语句。函数式编程有许多优点,包括:
- 代码更简洁、更易读
- 代码更容易测试和维护
- 代码更具并发性
如果你想了解更多关于函数式编程的内容,我推荐你可以阅读《JavaScript函数式编程指南》这本书。
以上就是我对JavaScript函数的特性的一些看法,希望对大家有所帮助。