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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM