參數(shù)分實參和虛參嘱吗,定義函數(shù)時的參數(shù)叫虛參增热,調(diào)用函數(shù)時候傳入?yún)?shù)的叫實參
本文主要小結(jié)一下平時編寫代碼時候遇到參數(shù)問題以及ES5整以、ES6中跟參數(shù)相關(guān)的語法
1.call和apply講解
定義如下:
apply:方法能劫持另外一個對象的方法,繼承另外一個對象的屬性.
Function.apply(obj,args)
方法能接收兩個參數(shù)
obj:這個對象將代替Function類里this對象
args:這個是數(shù)組峻仇,它將作為參數(shù)傳給Function(args--<arguments)
call:和apply的意思一樣,只不過是參數(shù)列表不一樣.
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:這個對象將代替Function類里this對象
params:這個是一個參數(shù)列表
這里我們主要解決以下幾個問題:
- apply和call的區(qū)別在哪里
- 什么情況下用apply,什么情況下用call
- apply的其他巧妙用法(一般在什么情況下可以使用apply)
看下面的例子
function Person(name,age){
this.name=name;
this.age=age
}
function Student(name,age,grade){
this.grade=grade;
Person.apply(this,arguments)
}
let studengtA=new Student('小A',10,'2年級')
console.log(studengtA);
輸出結(jié)果是:大家懂得....
分析: Person.apply(this,arguments);
this:在創(chuàng)建對象在這個時候代表的是student
arguments:是一個數(shù)組,也就是[“小A”,”10”,”2年級”];
也就是通俗一點講就是:執(zhí)行一次Person公黑,但其內(nèi)部的this被apply改變了
2.擴展運算符(...)
在 ES5 中,apply() 方法可以很方便將數(shù)組作為參數(shù)傳遞給函數(shù)摄咆,經(jīng)常用于使用 Math.max() 來取得數(shù)組的最大值凡蚜。看下面的代碼段:
//返回數(shù)組中的最大值
var myArray = [5, 10, 50];
Math.max(myArray); // Error: NaN
Math.max.apply(Math, myArray); // 50
Math.max() 方法不支持數(shù)組吭从,只接受數(shù)字作為參數(shù)朝蜘。當數(shù)組傳遞給函數(shù),函數(shù)會拋出錯誤涩金。但是當使用 apply() 方法后谱醇,數(shù)組變成了一個個單獨的數(shù)組傳遞給了函數(shù),所以 Math.max() 就能夠正確的執(zhí)行了步做。
幸運的是副渴,ES6 給我們帶來了擴展運算符,我們就不必再繼續(xù)使用 apply() 方法了全度。我們可以將表達式輕松的展開為多個參數(shù)煮剧。
var myArray = [5, 10, 50];
Math.max(...myArray); // 50
在這里我們通過擴展運算符將 myArray 展開成了一個個單獨的值。雖然 ES5 中我們可以通過 apply() 方法來模擬擴展運算符,但是語法上讓人迷惑轿秧,并且缺少可擴展性中跌。擴展運算符不僅易于使用,還帶來了許多新的特性菇篡。比如漩符,你可以在函數(shù)調(diào)用時多次使用擴展運算符,并且還可以和其他參數(shù)混合在一起驱还。
function myFunction() {
for(var i in arguments){
console.log(arguments[i]);
}
}
var params = [10, 15];
myFunction(5, ...params, 20, ...[25]); // 5 10 15 20 25
3.REST 參數(shù)
rest 參數(shù)和擴展運算符是一樣的語法嗜暴,但是他不是將數(shù)組展開成一個個的參數(shù),而是將一個個參數(shù)轉(zhuǎn)換為數(shù)組议蟆。
function myFunction(...options) {
console.log(options);
}
myFunction('a', 'b', 'c'); // ["a", "b", "c"]
如果沒有提供參數(shù)闷沥,rest 參數(shù)會被設(shè)置為空數(shù)組:
function myFunction(...options) {
console.log(options);
}
myFunction(); // []
創(chuàng)建參數(shù)數(shù)量可變的函數(shù):
ES5的寫法,利用arguments這個數(shù)組
//下面這個方法的作用是傳入多個參數(shù)咐容,判斷第二個開始的參數(shù)跟第一個是否相同
function checkSubstrings(string) {
for (var i = 1; i < arguments.length; i++) {
if (string.indexOf(arguments[i]) === -1) {
return false;
}
}
return true;
}
checkSubstrings('this is a string', 'is', 'this'); // true
ES6的寫法舆逃,利用rest
function checkSubstrings(string, ...keys) {
for (var key of keys) {
if (string.indexOf(key) === -1) {
return false;
}
}
return true;
}
checkSubstrings('this is a string', 'is', 'this'); // true
REST只能是最后一個參數(shù),否則會導(dǎo)致語法錯誤戳粒。
4.默認參數(shù)
ES5 中 JavaScript 并不支持默認值路狮,但這里有個很簡單的實現(xiàn),使用 OR
運算符(||)蔚约,我們可以很容易的模擬默認參數(shù)奄妨,看下面的代碼:
function foo(param1, param2) {
param1 = param1 || 10;
param2 = param2 || 10;
console.log(param1, param2);
}
foo(5, 5); // 5 5
foo(5); // 5 10
foo(); // 10 10
這種方法在函數(shù)內(nèi)很常用,但也存在瑕疵苹祟。如果傳遞 0
或者 null
也會返回默認值砸抛。因為它們被認為是 falsy 值。所以如果我們確實需要給函數(shù)傳遞 0
或者 null
树枫,我們需要換種方法來檢測參數(shù)是否缺失:
function foo(param1, param2) {
if(param1 === undefined){
param1 = 10;
}
if(param2 === undefined){
param2 = 10;
}
console.log(param1, param2);
}
foo(0, null); // 0, null
foo(); // 10, 10
雖然解決了傳0和null的不足直焙,但是代碼量多了且不優(yōu)雅
看下面ES6的寫法
function foo(a = 10, b = 10) {
console.log(a, b);
}
foo(5); // 5 10
foo(0, null); // 0 null
正如你所看到的,忽略參數(shù)返回了默認值团赏,但傳遞 0 或者 null 并沒有箕般。我們甚至可以使用函數(shù)來產(chǎn)生參數(shù)的默認值:
function getParam() {
alert("getParam was called");
return 3;
}
function multiply(param1, param2 = getParam()) {
return param1 * param2;
}
multiply(2, 5); // 10
multiply(2); // 6 (also displays an alert dialog)
需要注意的是耐薯,只有缺少第二個參數(shù)的時候舔清,gegParam 方法才會執(zhí)行,所以當我們使用兩個參數(shù) multiply() 的時候并不會彈出 alert曲初。
默認參數(shù)另一個有意思的特性是在方法聲明是可以引用其他參數(shù)和變量作為默認參數(shù):
function myFunction(a=10, b=a) {
console.log('a = ' + a + '; b = ' + b);
}
myFunction(); // a=10; b=10
myFunction(22); // a=22; b=22
myFunction(2, 4); // a=2; b=4
甚至可以在函數(shù)聲明的時候執(zhí)行操作符:
function myFunction(a, b = ++a, c = a*b) {
console.log(c);
}
myFunction(5); // 36
注意:不像其他語言体谒,JavaScript 是在調(diào)用時才計算默認參數(shù)的:
function add(value, array = []) {
array.push(value);
return array;
}
add(5); // [5]
add(6); // [6], not [5, 6]
5.解構(gòu)賦值
function fun({name}) {
console.log(name)
}
let boy={
name:'小明',
age:18
}
fun(boy);
6.類型檢查和缺失或多余參數(shù)
在強類型的語言中,我們必須在函數(shù)聲明時聲明參數(shù)的類型臼婆,但 JavaScript 中沒有這種特性抒痒,在 JavaScript 中,并不關(guān)心傳遞給函數(shù)的參數(shù)的類型和個數(shù)颁褂。
假設(shè)我們有一個函數(shù)故响,僅接受一個參數(shù)傀广。當我們調(diào)用這個函數(shù)的使用,我們并不限制到底傳遞給函數(shù)多少個參數(shù)彩届,甚至可以選擇不傳伪冰,都不會產(chǎn)生錯誤。
參數(shù)的個數(shù)可以分為兩種情況:
- 參數(shù)缺失樟蠕,缺失的變量賦值為 undefined
- 參數(shù)過多
強制參數(shù)
函數(shù)調(diào)用中如果函數(shù)缺失贮聂,它會被設(shè)置為 undefined。我們可以利用這一點寨辩,如果參數(shù)缺失就拋出錯誤:
function foo(mandatory, optional) {
if (mandatory === undefined) {
throw new Error('Missing parameter: mandatory');
}
}
在 ES6 中吓懈,我們可以更近一步,使用默認參數(shù)來設(shè)置強制參數(shù):
function throwError() {
throw new Error('Missing parameter');
}
function foo(param1 = throwError(), param2 = throwError()) {
// do something
}
foo(10, 20); // ok
foo(10); // Error: missing parameter
參數(shù)個數(shù)
ES6:用REST的length
ES5:用arguments的length(arguments在每個函數(shù)內(nèi)都存在靡狞,是一個類數(shù)組)