天天看點

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
           

參數傳遞

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
           

部落格: https://blog.86886.wang

GitHub: https://github.com/wmui