在 JS 里函数是一等公民
理解函数参数
定义一个函数 test
function test(arg1, arg2) {
console.log("Hello " + arg1 + " " + arg2);
return "Hello " + arg1 + " " + arg2;
}
屏幕快照 2020-03-10 14.17.26.png
test 函数有两个参数,但是这两个参数可传可不传,函数都不会报错。
这是因为 ECMAScript 中的参数在内部是用一个数组表示的,函数接收到的始终都是这个数组,而不关心这个数组中有没有元素,有多少个元素。实际上,在函数内部可以通过 argumnets 对象来访问参数数组,从而获取到函数的参数,所以上面的函数也可以改写为
function test() {
console.log("Hello " + arguments[0] + " " + arguments[1]);
return "Hello " + arguments[0] + " " + arguments[1];
}
屏幕快照 2020-03-10 14.20.28.png
利用 arguments JS 可以模拟重载
function doAdd() {
if (arguments.length === 1) {
console.log(arguments[0] + 10)
} else if (arguments.length === 2) {
console.log(arguments[0] + arguments[1])
}
}
屏幕快照 2020-03-10 14.26.25.png
ECMAScript 中所有参数都是值传递,不可能通过引用传递参数
1.当参数是基本数据类型时,被传递的值会被复制给命名参数,或者说复制给 arguments 对象中的一个元素
function add (num) {
num += 10
return num
}
var count = 20
var result = add(count)
console.log(count)
console.log(result)
屏幕快照 2020-03-10 14.59.36.png
可以看到,当 count 传递到函数内部进行运算之后,count 的值并没有发生改变,说明 num 和 count 并没有什么关系,只是具有相同的值。
2.当参数为引用类型值的时候,可能会造成一些困惑
var person = {}
function setName(obj) {
obj.name = 'John'
}
setName(person)
console.log(person)
屏幕快照 2020-03-10 15.06.00.png
看到这个结果可能就任务引用数据类型参数是按照引用传递的,但是把这个函数稍微做下改造
var person = {}
function setName(obj) {
obj.name = 'John'
obj = {}
obj.name = 'alex'
}
setName(person)
console.log(person)
屏幕快照 2020-03-10 15.10.06.png
如果参数 obj 是按引用传递的,那么在函数的第二行,引用被指向了一个新对象,那么当再次打印 person 时,打印的应该是 name 为 alex 的对象,但是结果却不是,这说明,当参数是引用类型时,实际上是把引用类型对象在栈内存中的指针复制了一份传递给函数