最近公司有一个项目出现了bug让我去解决,发现之前的同事直接在函数里面修改了形参导致的问题那么Java Script可以直接修改函数的形参吗?
我们看一下下面的几个例子。
var a = 10;
function fn(a) {
a = 20;
console.log(a, arguments[0]); // 20 20
}
fn(a)
console.log(a) // 10
变量a没有被修改
var param = {
name: 'Jack',
age: '18',
}
function fn(param){
param.name = "Lucy"
}
fn(param);
console.log(param.name) // Lucy
param.name被修改了。
这里面涉及到深克隆的问题,Javascript数据类型分为基本数据类型(Number,String,Boolean,Undefined,Null)和引用数据类型(Object,Array,Function)。基本数据类型的值存放在栈中,将一个基本数据类型赋值给一个变量就是将他的值复制了一份,引用数据类型的链接地址存放在栈中连接地址指向堆中的值,将引用类型复制一份其实是将他的链接赋值给新的变量两个变量指向同一个值。
再来看看forEach和map会不会修改原数据。
var student = [
{
name: 'Jack',
age: '18',
},
{
name: 'Lucy',
age: '20',
},
]
student.forEach((item) => { item.age = 25 })
console.log(student);
// { name: 'Jack', age: '25', },
// { name: 'Lucy', age: '25', },
student.map((item) => { item.age = 30 })
console.log(student);
// { name: 'Jack', age: '30', },
// { name: 'Lucy', age: '30', },
forEach和map的定义区别就是forEact没有返回值map有返回值,forEach会修改原数据这道不奇怪,奇怪的是map也修改了原数据这和map的设计思想不太一样,这应该算是js的一种缺陷,在实际应用中使用map就是不想修改原数据因为map会返回一个新数组。如果不想原数据被改变可以使用这种方法。
const results = student.map((item) => ({ ...item, age: 30 }))