对于函数的参数都是按值传递的理解,常常会使人难以理解,特别参数是对象的时候,总是看起来像是引用传递;下面用几个例子来解释:
一、函数参数的几种数据类型:
1、 参数是基本数据类型,这个按值传递,比较容易理解
// 参数是基本数据类型,这个按值传递,比较容易理解let num = 1;function changeNum(arg1) { ++arg1;}changeNum(num);console.log(num); // 打印出1复制代码
2、参数是对象,乍一看以为是引用传递
let person = { name: 'xl', skill: ['js', 'css', 'html']};function changeObj(obj) { obj.name = 'otherName';}changeObj(person);console.log(person); // {name: 'otherName', skill: ['js', 'css', 'html']}复制代码
3、参数是对象的另一种情况,让人又摸不到头脑了
let person = { name: 'xl', skill: ['js', 'css', 'html']};function changeObj(obj) { obj = { name: 'otherName' };}changeObj(person);console.log(person); // {name: 'xl', skill: ['js', 'css', 'html']}// 如果参数是按引用传递的,那么执行changeObj(person) 的时候:person = { name: 'otherName'};// person岂不是变成另一个对象了,为什么实际又是原对象呢?复制代码
4、参数是函数(对象)的情况
let color = 'blue';let obj = { color: 'red', sayColor() { console.log(this.color); }};function fn(callback) { callback();}fn(obj.sayColor); // 'blue'// 上面的运行结果,真的是超乎想象,打印出的竟然是'blue'复制代码
二、函数参数传递的理解
1、到底函数的参数是怎么传递的呢?下面是一种看起来比较合理的猜想
function fn(arg1, arg2) { // 在函数里面,一开始就执行:申明并赋值操作 let arg1 = arguments[0], arg2 = arguments[1];}复制代码
三、验证猜想 :
1、参数是对象的另一种情况,让人又摸不到头脑了
let person = { name: 'xl', skill: ['js', 'css', 'html']}function changeObj(obj) { let obj = argument[0]; // 让obj重新指向另一个对象 obj = { name: 'otherName' };}changeObj(person);// 实际函数执行分析:// function changeObj(obj) { let obj = person; obj = { name: 'otherName' };// }// 最后person没有变化,合理复制代码
2、参数是函数(对象)的情况
let color = 'blue';let obj = { color: 'red', sayColor() { console.log(this.color); }};function fn(callback) { callback();}fn(obj.sayColor); // 'blue'// 实际函数执行分析:// function fn(callback) { let callback = function () { console.log(this.color); } callback(); // 函数中的this指向widow,因此this.color是blue// }复制代码