JS对象类型-函数篇-函数参数
JS中函数定义时不需要指定参数的类型,函数调用时也不会对传入的参数进行类型检查,甚至参数的个数也不做检查,了解这些特殊情况,避免开发出错。
参数个数
当实参比形参的个数少时,多余的形参会被设置成undefined。
function fn(a,b,c){
console.log(c) // undefined
}
fn(1,2)
当实参比形参的个数多时,多余的实参在函数中无法直接获取到,可以通过arguments对象获取。
function fn(a,b) {
console.log(arguments[0],arguments[1],arguments[2]) // 1 2 3
}
fn(1,2,3)
JS函数中的参数在内部是用一个数组表示的,可以通过arguments对象访问这个参数数组,从而获取到传入给函数的每一个参数。
注意: arguments对象是一个类数组对象,不是Array对象的实例。可以使用方括号语法访问每一个元素。
arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数。
function fn(a,b) {
console.log(arguments.length) // 3
console.log(fn.length) // 2
}
fn(1,2,3)
参数同步
在严格模式下,arguments对象的值和形参是独立的。在非严格模式下,它们的值是同步的。
// 示例1
function fn(a) {
'use strict'
console.log(a, arguments[0]) // 1 1
a = 2
console.log(a, arguments[0]) // 2 1
arguments[0] = 3
console.log(a, arguments[0]) // 2 3
}
fn(1)
// 示例2
function fn(a) {
console.log(a, arguments[0]) // 1 1
a = 2
console.log(a, arguments[0]) // 2 2
arguments[0] = 3
console.log(a, arguments[0]) // 3 3
}
fn(1)
callee属性
arguments对象的callee属性是一个指针,指向拥有这个arguments对象的函数。
注意: 严格模式下禁止使用该属性,会报错
// 阶层函数
function factorial(num) {
if(num <=1) {
return 1
} else {
return num * factorial(num - 1)
}
}
factorial(3) // 6
上面的函数有一个问题,就是函数的执行和函数名耦合在了一起,这时可以使用callee属性解决这个问题。
function factorial(num) {
if(num <=1) {
return 1
} else {
return num * arguments.callee(num - 1)
}
}
factorial(3) // 6
由于callee属性在严格模式下报错,可以使用具名函数表达式。
var factorial = function fn(num){
if(num <=1){
return 1
}else {
return num * fn(num - 1)
}
}
factorial(3) // 6
caller属性
arguments对象的caller属性不是一个标准属性,不赞成用于生产环境,但浏览器都支持它。该属性保存了调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值是null。
注意: 严格模式下禁止使用该属性,会报错
// 示例1
function outer() {
inner()
}
function inner() {
// inner是当前函数,outer是调用当前函数的函数
console.log(inner.caller) // outer() { inner() }
}
outer()
// 示例2
function inner() {
console.log(inner.caller)
}
inner() // null
函数重载
函数重载简单理解就是同一个函数,可以根据不同的参数(比如类型不同或数量不同)执行不同的处理逻辑。
由于JS无法为同一个函数编写不同的定义标签,所以真正的重载是做不到的,只能通过检查传入函数中参数的类型和数量作出不同的反应,来模仿方法的重载。
function doAdd(){
if(arguments.length == 1){
alert(arguments[0] + 10);
}else if(arguments.length == 2){
alert(arguments[0] + arguments[1]);
}
}
doAdd(10);//20
doAdd(30,20);//50
参数传递
【基本类型值】向参数传递基本类型值时,被传递的值会复制给一个局部变量(命名参数或arguments对象中的一个元素)
function fn(num) {
num += 10
return num
}
var count = 10
var result = fn(count)
console.log(count) // 10 原始值不会改变
console.log(result) // 20
【引用类型值】向参数传递引用类型值时,被传递的值的引用地址复制给一个局部变量,所以局部变量的变化会反映到外部函数上。
function fn(obj) {
obj.name = 'hello'
}
var person = new Object()
fn(person)
console.log(person.name) // 'hello'
如果在函数内部重写引用类型的形参,被传递的值就会成为一个局部变量,局部变量会在函数执行结束后立即销毁
function fn(obj) {
obj = new Object();
obj.name = 'hello';
}
var person = new Object()
fn(person)
console.log(person.name) // undefined
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步