天将降大任于斯人也,必先苦其心志,劳其筋骨,空乏其身,行弗乱其所为。所以动心忍性,增益其所不能。
刚才我在学习《JavaScript高级程序设计 第4版》的4.1.3 传递参数时,我反复阅读并实验思考了这章的内容,我觉得有问题。
我们来看看书上的例子
`function setName(obj){ obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; }let person = new Object(); setName(person); console.log(person.name); //Nicholas `
我们先从函数传值是按值传递的视角去看。在说这些之前,我们要知道函数参数是一个函数的局部变量,解释过来就是,setName函数接收到的person参数,在函数内部大概是这样: `let obj = person;`. 现在开始看,我将person传入函数参数,但是我是按值传递的,意思就是我是传的堆内存中的对象值给它的,但是这个对象值被obj这个局部变量接收了,意思就是我操作的还是一个引用(我们是无法直接操作堆内存中的对象的,必须借助引用,也就是借助变量)。 `{name: 'wode'}.age = 28;`这段代码将报错。 函数体里面的代码就很好理解了: 改变obj引用所引用的堆内存空间中的对象的name属性,然后把obj引用地址改变为另一个新对象地址,再通过obj引用改变新对象的name属性。这就是为什么在最后打印出来的是Nicholas。
我们再来看看函数船只是按引用传递的视角。我将person引用传入函数, `let obj = person;`引用被复制到另一个引用,函数体内的过程也很明显,obj引用的堆内存中的对象的name属性被赋值为Nicholas,再将obj引用变为一个新对象,将新对象的name赋值为Greg,最后,打印出来的依然是Nicholas。
那我现在再提出这个疑问:函数传参真的是值得传递吗?