1638012060
関数のパラメーターと引数は、最も紛らわしい用語の1つです。この投稿は、パラメーターと引数が何であるか、およびそれらの違いについて学ぶのに役立ちます。また、引数オブジェクト、RESTおよびデフォルトのパラメーター、値および参照型についても学習します。
パラメータは関数定義の一部です。関数を宣言するときに、関数が受け入れる変数のリストを指定することもできます。これらの変数は、関数パラメーターまたはパラメーターと呼ばれます。関数は無制限の数のパラメーターを持つことができます。複数のパラメーターがある場合は、それらをコンマで区切ります。
// Function definition syntax (declaration):
function functionName(param1, param2) {
// function body
}
// Function definition syntax (expression):
const functionName = function(param1, param2) {
// function body
}
// Function without parameters:
function generateRandomNumber() {
return Math.floor(Math.random() * 1000)
}
// Function with one parameter:
function generateRandomNumberWithLimit(upperLimit) {
return Math.floor(Math.random() * upperLimit)
}
// Function with two parameters:
function multiplyNumbers(a, b) {
return a * b
}
いくつかの関数を呼び出し、その関数にいくつかの値を渡すと、これらの値は関数引数または引数と呼ばれます。
// Create a function:
function divideNumbers(x, y) {
return x / y
}
// Invoke divideNumbers function:
// The 65623 and 432 are arguments
// passed to the divideNumbers
divideNumbers(65623, 432)
// Output:
// 151.90509259259258
関数に引数を渡すと、バックグラウンドでいくつかのことが起こります。まず、JavaScriptは、これらの変数のパラメーターの名前を使用して、関数のパラメーターに基づいて新しい変数を作成します。次に、JavaScriptは、関数を呼び出したときに渡した引数を使用してこれらの変数を初期化します。
この初期化プロセス中に、JavaScriptはプリミティブ値を値ごとにコピーします。オブジェクトを渡すと、JavaScriptはそれらを参照によってコピーします。これらの変数は関数に対してローカルになります。それらはその中にのみ存在します。これは、外部からこれらの変数にアクセスできないことを意味します。
これらの変数は、関数呼び出し中にのみ存在します。関数呼び出しが終了すると、これらの変数は失われます。
上で、プリミティブ値とオブジェクトは、引数として渡すと異なる方法で処理されることを説明しました。JavaScriptには、2種類のデータがあります。string、number、bigint、boolean、symbol、undefined、nullなどのプリミティブデータ型があります。次に、オブジェクトがあります。
プリミティブデータ型も「値型」のグループに属します。オブジェクトは「参照型」と呼ばれるグループに属しています。値型は値によってコピーされます。参照タイプは参照によってコピーされます。これは、意図しない結果につながる可能性があるため、関数パラメーターと引数の観点から重要です。
プリミティブ値を関数に渡すと、JavaScriptはそのコピーを作成し、関数のローカル変数に割り当てます。これは、2つの同一のデータがあることを意味します。1つはオリジナルになり、2つ目はコピーになります。関数内でコピーを変更しようとしているとしましょう。
値型の場合、元の値はそのまま残ります。関数内で引数に加えた変更は、元の関数には影響しません。
// Create a variable and assign it a primitive value:
const num = 7
// Create a function with one parameter:
function randomFunc(randomNumber) {
// Try to change the value of "randomNumber":
randomNumber = 11
// Return the new value of "randomNumber":
return randomNumber
}
// Invoke the "randomFunc":
randomFunc(limit)
// Output:
// 11
// Log the value of "num" variable:
console.log(num)
// Output:
// 7
これは、参照型またはオブジェクトには適用されません。変数を宣言し、それにオブジェクトを割り当てたとしましょう。次に、その変数を引数として関数に渡します。オブジェクトは参照型です。これは、オブジェクト全体を渡していないことを意味します。代わりに、そのオブジェクトへの参照のみを渡します。
オブジェクトの参照を渡すと、これはJavaScriptがコピーして、関数のローカル変数に割り当てるものでもあります。現時点では、2つのデータはありません。まだ元のデータは1つだけです。ただし、そのオリジナルへの参照は2つあります。ここから問題が始まります。
偶然または故意に、引数、オブジェクトを変更しようとすると、変更はローカルのままになりません。変更により、実際には元のオブジェクトが変更されます。
// Create a simple object:
const user = {
name: 'joe',
email: 'joe@joe.ci',
loggedIn: false
}
// Create a function with one parameter:
function randomFunc(userObj) {
// Try to change the value of "loggedIn" property
// that exists on the userObj argument:
userObj.loggedIn = true
// Return the altered userObj argument:
return userObj
}
// Invoke the "randomFunc":
randomFunc(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: true // <= The value of "loggedIn" property changed
// }
// Log the value of the original "user" object:
console.log(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: true // <= The value of "loggedIn" property changed
// }
上記の例loggedIn
では、引数オブジェクトのプロパティの値を変更しようとしました。その結果loggedIn
、元のオブジェクトのの値も変更しました。これは、2つのオブジェクトではなく、同じオブジェクトへの2つの参照を処理していたために発生するはずでした。
オブジェクトを操作しながら、これを防ぐことができます。オブジェクトの実際のコピーを手動で作成してから、そのコピーを変更できます。これを行う1つの方法は、spread構文を使用することです。
// Create a simple object:
const user = {
name: 'joe',
email: 'joe@joe.ci',
loggedIn: false
}
// Create a function with one parameter:
function randomFunc(userObj) {
// Create real copy of userObj using spread syntax:
const newUserObj = { ...userObj }
// Change the value of "loggedIn" property
// that exists on the "newUserObj" object:
newUserObj.loggedIn = true
// Return the altered "newUserObj" object:
return newUserObj
}
// Invoke the "randomFunc":
randomFunc(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: true // <= The value of "loggedIn" property changed
// }
// Log the value of the original "user" object:
console.log(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: false // <= The value of "loggedIn" property stayed the same
// }
今では、関数のパラメーターと引数が異なるものであることはおそらく理にかなっています。しかし、これは私が言っていることではありません。私が実際に意味しているのは、これです。JavaScriptは、定義したパラメーターの数と渡した引数の数をチェックしません。たとえば、2つのパラメーターを持つ関数を作成するとします。
この関数を呼び出して、10個の引数を渡すことができます。JavaScriptは気にしません。関数を正常に呼び出し、すべてのパラメーターの変数を作成して割り当て、関数を実行します。スローされたエラーは1つもありません。パラメータよりも少ない引数を渡すとどうなりますか?省略した引数はに設定されundefined
ます。
// Create a function with three parameters:
function myFunc(param1, param2, param3) {
// Return all parameters as an array:
return [param1, param2, param3]
}
// Invoke "myFunc" with all three parameters:
myFunc('one', 'two', 'three')
// Output:
// [ 'one', 'two', 'three' ]
// Invoke "myFunc" with two parameters:
myFunc('one', 'two')
// Output:
// [ 'one', 'two', undefined ]
// Invoke "myFunc" with five parameters:
myFunc('one', 'two', 'three', 'four', 'five')
// Output:
// [ 'one', 'two', 'three' ]
これのポイントは簡単です。関数を呼び出すときは、必要なすべての引数を必ず渡してください。一部の引数を見逃したり、必要以上の引数を渡したりしても、JavaScriptは警告を表示しないことに注意してください。
関数を呼び出すと、いくつかの興味深いことが起こります。それらの1つは、JavaScriptがarguments
。と呼ばれる配列のようなオブジェクトも作成することです。このオブジェクトには、関数に渡したすべての引数が含まれています。このオブジェクトを使用して、すべての引数とその値にアクセスできます。
// Create a function:
function assembleTeam(member1, member2, member3) {
// Log the whole arguments object:
console.log(arguments)
// Log the length of arguments object:
console.log('length: ', arguments.length)
// Return new team as an array:
return `Team: [${member3}, ${member2}, ${member1}]`
}
// Invoke the "assembleTeam" function:
assembleTeam('Clark', 'Cindy', 'Joshua')
// Output:
// {
// '0': 'Clark',
// '1': 'Cindy',
// '2': 'Joshua',
// length: 3,
// callee: ƒ assembleTeam(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
// 'length: ' 3
// 'Team: [Joshua, Cindy, Clark]'
必要なすべての引数ではなく、渡したすべての引数について話していることに注意してください。必要以上の引数を渡すと、arguments
オブジェクトにはこれらの追加の引数も含まれます。これは、arguments
オブジェクトが配列のようなインデックスを介して追加の引数にアクセスする方法を提供することを意味します。
// Create a function:
function readNumbers(number1, number2, number3) {
// Log the whole arguments object:
console.log(arguments)
// Log the 7th argument:
console.log(arguments[7])
// Return all numbers as an array:
return `Numbers are: [${number1}, ${number2}, ${number3}]`
}
// Invoke the "readNumbers" function:
readNumbers(1, 2, 3, 4, 5, 6, 7, 8, 9)
// Output:
// {
// '0': 1,
// '1': 2,
// '2': 3,
// '3': 4,
// '4': 5,
// '5': 6,
// '6': 7,
// '7': 8,
// '8': 9,
// length: 9,
// callee: ƒ readNumbers(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
// 'The 7th argument is: 8'
// 'Numbers are: [1, 2, 3]'
渡す引数の数が必要より少ない場合、JavaScriptを省略した引数は、それらをに設定しますundefined
。そうは言っても、これらの欠落している引数はarguments
オブジェクトに表示されません。
// Create a function:
function readNumbers(number1, number2, number3) {
// Log the whole arguments object:
console.log(arguments)
// Return all numbers as an array:
return `Numbers are: [${number1}, ${number2}, ${number3}]`
}
// Invoke the "readNumbers" function with a single argument:
readNumbers(1)
// Output:
// {
// '0': 1,
// length: 1,
// callee: ƒ readNumbers(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
// 'Numbers are: [1, undefined, undefined]'
ES6以降では、restパラメーターを使用して、関数が無数のパラメーターを受け入れるように指定することもできます。このRESTパラメーターは、すべての引数を含む配列を作成します。これらの引数にアクセスするには、restパラメーターの名前を使用できます。
言及する1つのこと。通常のパラメーターと一緒にRESTパラメーターを使用する場合、RESTパラメーターは常に最後に来る必要があります。順序が異なるとエラーが発生します。
// Create a function with rest parameter:
function readNumbers(...numbers) {
return numbers
}
// Invoke "readNumbers" function:
readNumbers(5, 8, 99, 63)
// Output:
// [ 5, 8, 99, 63 ]
// Create a function with normal and also rest parameter:
function readNumbers(number1, number2, ...numbers) {
return [number1, number2, numbers]
}
// Invoke "readNumbers" function:
readNumbers(15, 18, 89, 639)
// Output:
// [ 15, 18, [ 89, 639 ] ]
ご覧のとおり、restパラメーターはarguments
オブジェクトと同じではありません。1つの違いは、RESTパラメーターが実数配列であることです。あなたのような方法でそれを反復することができmap()
、sort()
、reduce()
、forEach()
。arguments
オブジェクトでそれを試してください。もう一つの違いは内容です。
arguments
オブジェクトは、関数に渡されるすべての引数が含まれています。restパラメーターには、一致するパラメーターを持たない追加の引数のみが含まれます。したがって、1つのパラメーターとRESTパラメーターを持つ関数があるとします。3つの引数を渡すと、restパラメーターには最後の2つだけが含まれます。
arguments
オブジェクトは、他の一方で、すべての引数、最初に通常と同様に残りの部分を含んでいます。
// Create a function with normal and also rest parameter:
function readNumbers(num1, num2, ...nums) {
console.log('num1: ', num1)
console.log('num2: ', num2)
console.log('nums: ', nums)
}
// Invoke "readNumbers" function:
readNumbers(1, 3, 5, 7, 12)
// Output:
// 'num1: ' 1
// 'num2: ' 3
// 'nums: ' [ 5, 7, 12 ]
// Create a function with two parameters:
function readNumbers(num1, num2) {
console.log(arguments)
}
// Invoke "readNumbers" function:
readNumbers(1, 3, 5, 7, 12)
// Output:
// {
// '0': 1,
// '1': 3,
// '2': 5,
// '3': 7,
// '4': 12,
// length: 5,
// callee: ƒ readNumbers(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
JavaScriptは、省略された引数をに設定しundefined
ます。フォールバック値を作成することで、これを回避できます。これは、デフォルトのパラメータを使用して実現できます。関数とそのパラメーターを定義するときは、代入演算子といくつかの値を使用して、各パラメーターのデフォルト値を定義できます。
後で関数を呼び出して必要な引数を指定しない場合、JavaScriptはundefined
。の代わりにデフォルト値を使用します。何らかの値を指定すると、JavaScriptはデフォルトの代わりにその値を使用します。
// Create a function with one parameter
// and set the default value of the parameter to "Anonymous":
function greetUser(username = 'Anonymous') {
return `Hello, ${username}!`
}
// Invoke the "greetUser" function without argument:
greetUser()
// Output:
// 'Hello, Anonymous!'
// Invoke the "greetUser" function with an argument:
greetUser('Timothy')
// Output:
// 'Hello, Timothy!'
関数のパラメーターと引数は混乱を招く可能性があります。この投稿によって、パラメーターと引数が何であるか、およびそれらがどのように異なるかを理解しやすくなることを願っています。また、この投稿が、argumentsオブジェクトとrestおよびdefaultパラメーターの使用方法を学ぶのに役立つことを願っています。
この記事が気に入ったら、今後の投稿を見逃さないように購読してください。
リンク: https://blog.alexdevero.com/function-parameters-arguments/
1638012060
関数のパラメーターと引数は、最も紛らわしい用語の1つです。この投稿は、パラメーターと引数が何であるか、およびそれらの違いについて学ぶのに役立ちます。また、引数オブジェクト、RESTおよびデフォルトのパラメーター、値および参照型についても学習します。
パラメータは関数定義の一部です。関数を宣言するときに、関数が受け入れる変数のリストを指定することもできます。これらの変数は、関数パラメーターまたはパラメーターと呼ばれます。関数は無制限の数のパラメーターを持つことができます。複数のパラメーターがある場合は、それらをコンマで区切ります。
// Function definition syntax (declaration):
function functionName(param1, param2) {
// function body
}
// Function definition syntax (expression):
const functionName = function(param1, param2) {
// function body
}
// Function without parameters:
function generateRandomNumber() {
return Math.floor(Math.random() * 1000)
}
// Function with one parameter:
function generateRandomNumberWithLimit(upperLimit) {
return Math.floor(Math.random() * upperLimit)
}
// Function with two parameters:
function multiplyNumbers(a, b) {
return a * b
}
いくつかの関数を呼び出し、その関数にいくつかの値を渡すと、これらの値は関数引数または引数と呼ばれます。
// Create a function:
function divideNumbers(x, y) {
return x / y
}
// Invoke divideNumbers function:
// The 65623 and 432 are arguments
// passed to the divideNumbers
divideNumbers(65623, 432)
// Output:
// 151.90509259259258
関数に引数を渡すと、バックグラウンドでいくつかのことが起こります。まず、JavaScriptは、これらの変数のパラメーターの名前を使用して、関数のパラメーターに基づいて新しい変数を作成します。次に、JavaScriptは、関数を呼び出したときに渡した引数を使用してこれらの変数を初期化します。
この初期化プロセス中に、JavaScriptはプリミティブ値を値ごとにコピーします。オブジェクトを渡すと、JavaScriptはそれらを参照によってコピーします。これらの変数は関数に対してローカルになります。それらはその中にのみ存在します。これは、外部からこれらの変数にアクセスできないことを意味します。
これらの変数は、関数呼び出し中にのみ存在します。関数呼び出しが終了すると、これらの変数は失われます。
上で、プリミティブ値とオブジェクトは、引数として渡すと異なる方法で処理されることを説明しました。JavaScriptには、2種類のデータがあります。string、number、bigint、boolean、symbol、undefined、nullなどのプリミティブデータ型があります。次に、オブジェクトがあります。
プリミティブデータ型も「値型」のグループに属します。オブジェクトは「参照型」と呼ばれるグループに属しています。値型は値によってコピーされます。参照タイプは参照によってコピーされます。これは、意図しない結果につながる可能性があるため、関数パラメーターと引数の観点から重要です。
プリミティブ値を関数に渡すと、JavaScriptはそのコピーを作成し、関数のローカル変数に割り当てます。これは、2つの同一のデータがあることを意味します。1つはオリジナルになり、2つ目はコピーになります。関数内でコピーを変更しようとしているとしましょう。
値型の場合、元の値はそのまま残ります。関数内で引数に加えた変更は、元の関数には影響しません。
// Create a variable and assign it a primitive value:
const num = 7
// Create a function with one parameter:
function randomFunc(randomNumber) {
// Try to change the value of "randomNumber":
randomNumber = 11
// Return the new value of "randomNumber":
return randomNumber
}
// Invoke the "randomFunc":
randomFunc(limit)
// Output:
// 11
// Log the value of "num" variable:
console.log(num)
// Output:
// 7
これは、参照型またはオブジェクトには適用されません。変数を宣言し、それにオブジェクトを割り当てたとしましょう。次に、その変数を引数として関数に渡します。オブジェクトは参照型です。これは、オブジェクト全体を渡していないことを意味します。代わりに、そのオブジェクトへの参照のみを渡します。
オブジェクトの参照を渡すと、これはJavaScriptがコピーして、関数のローカル変数に割り当てるものでもあります。現時点では、2つのデータはありません。まだ元のデータは1つだけです。ただし、そのオリジナルへの参照は2つあります。ここから問題が始まります。
偶然または故意に、引数、オブジェクトを変更しようとすると、変更はローカルのままになりません。変更により、実際には元のオブジェクトが変更されます。
// Create a simple object:
const user = {
name: 'joe',
email: 'joe@joe.ci',
loggedIn: false
}
// Create a function with one parameter:
function randomFunc(userObj) {
// Try to change the value of "loggedIn" property
// that exists on the userObj argument:
userObj.loggedIn = true
// Return the altered userObj argument:
return userObj
}
// Invoke the "randomFunc":
randomFunc(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: true // <= The value of "loggedIn" property changed
// }
// Log the value of the original "user" object:
console.log(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: true // <= The value of "loggedIn" property changed
// }
上記の例loggedIn
では、引数オブジェクトのプロパティの値を変更しようとしました。その結果loggedIn
、元のオブジェクトのの値も変更しました。これは、2つのオブジェクトではなく、同じオブジェクトへの2つの参照を処理していたために発生するはずでした。
オブジェクトを操作しながら、これを防ぐことができます。オブジェクトの実際のコピーを手動で作成してから、そのコピーを変更できます。これを行う1つの方法は、spread構文を使用することです。
// Create a simple object:
const user = {
name: 'joe',
email: 'joe@joe.ci',
loggedIn: false
}
// Create a function with one parameter:
function randomFunc(userObj) {
// Create real copy of userObj using spread syntax:
const newUserObj = { ...userObj }
// Change the value of "loggedIn" property
// that exists on the "newUserObj" object:
newUserObj.loggedIn = true
// Return the altered "newUserObj" object:
return newUserObj
}
// Invoke the "randomFunc":
randomFunc(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: true // <= The value of "loggedIn" property changed
// }
// Log the value of the original "user" object:
console.log(user)
// Output:
// {
// name: 'joe',
// email: 'joe@joe.ci',
// loggedIn: false // <= The value of "loggedIn" property stayed the same
// }
今では、関数のパラメーターと引数が異なるものであることはおそらく理にかなっています。しかし、これは私が言っていることではありません。私が実際に意味しているのは、これです。JavaScriptは、定義したパラメーターの数と渡した引数の数をチェックしません。たとえば、2つのパラメーターを持つ関数を作成するとします。
この関数を呼び出して、10個の引数を渡すことができます。JavaScriptは気にしません。関数を正常に呼び出し、すべてのパラメーターの変数を作成して割り当て、関数を実行します。スローされたエラーは1つもありません。パラメータよりも少ない引数を渡すとどうなりますか?省略した引数はに設定されundefined
ます。
// Create a function with three parameters:
function myFunc(param1, param2, param3) {
// Return all parameters as an array:
return [param1, param2, param3]
}
// Invoke "myFunc" with all three parameters:
myFunc('one', 'two', 'three')
// Output:
// [ 'one', 'two', 'three' ]
// Invoke "myFunc" with two parameters:
myFunc('one', 'two')
// Output:
// [ 'one', 'two', undefined ]
// Invoke "myFunc" with five parameters:
myFunc('one', 'two', 'three', 'four', 'five')
// Output:
// [ 'one', 'two', 'three' ]
これのポイントは簡単です。関数を呼び出すときは、必要なすべての引数を必ず渡してください。一部の引数を見逃したり、必要以上の引数を渡したりしても、JavaScriptは警告を表示しないことに注意してください。
関数を呼び出すと、いくつかの興味深いことが起こります。それらの1つは、JavaScriptがarguments
。と呼ばれる配列のようなオブジェクトも作成することです。このオブジェクトには、関数に渡したすべての引数が含まれています。このオブジェクトを使用して、すべての引数とその値にアクセスできます。
// Create a function:
function assembleTeam(member1, member2, member3) {
// Log the whole arguments object:
console.log(arguments)
// Log the length of arguments object:
console.log('length: ', arguments.length)
// Return new team as an array:
return `Team: [${member3}, ${member2}, ${member1}]`
}
// Invoke the "assembleTeam" function:
assembleTeam('Clark', 'Cindy', 'Joshua')
// Output:
// {
// '0': 'Clark',
// '1': 'Cindy',
// '2': 'Joshua',
// length: 3,
// callee: ƒ assembleTeam(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
// 'length: ' 3
// 'Team: [Joshua, Cindy, Clark]'
必要なすべての引数ではなく、渡したすべての引数について話していることに注意してください。必要以上の引数を渡すと、arguments
オブジェクトにはこれらの追加の引数も含まれます。これは、arguments
オブジェクトが配列のようなインデックスを介して追加の引数にアクセスする方法を提供することを意味します。
// Create a function:
function readNumbers(number1, number2, number3) {
// Log the whole arguments object:
console.log(arguments)
// Log the 7th argument:
console.log(arguments[7])
// Return all numbers as an array:
return `Numbers are: [${number1}, ${number2}, ${number3}]`
}
// Invoke the "readNumbers" function:
readNumbers(1, 2, 3, 4, 5, 6, 7, 8, 9)
// Output:
// {
// '0': 1,
// '1': 2,
// '2': 3,
// '3': 4,
// '4': 5,
// '5': 6,
// '6': 7,
// '7': 8,
// '8': 9,
// length: 9,
// callee: ƒ readNumbers(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
// 'The 7th argument is: 8'
// 'Numbers are: [1, 2, 3]'
渡す引数の数が必要より少ない場合、JavaScriptを省略した引数は、それらをに設定しますundefined
。そうは言っても、これらの欠落している引数はarguments
オブジェクトに表示されません。
// Create a function:
function readNumbers(number1, number2, number3) {
// Log the whole arguments object:
console.log(arguments)
// Return all numbers as an array:
return `Numbers are: [${number1}, ${number2}, ${number3}]`
}
// Invoke the "readNumbers" function with a single argument:
readNumbers(1)
// Output:
// {
// '0': 1,
// length: 1,
// callee: ƒ readNumbers(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
// 'Numbers are: [1, undefined, undefined]'
ES6以降では、restパラメーターを使用して、関数が無数のパラメーターを受け入れるように指定することもできます。このRESTパラメーターは、すべての引数を含む配列を作成します。これらの引数にアクセスするには、restパラメーターの名前を使用できます。
言及する1つのこと。通常のパラメーターと一緒にRESTパラメーターを使用する場合、RESTパラメーターは常に最後に来る必要があります。順序が異なるとエラーが発生します。
// Create a function with rest parameter:
function readNumbers(...numbers) {
return numbers
}
// Invoke "readNumbers" function:
readNumbers(5, 8, 99, 63)
// Output:
// [ 5, 8, 99, 63 ]
// Create a function with normal and also rest parameter:
function readNumbers(number1, number2, ...numbers) {
return [number1, number2, numbers]
}
// Invoke "readNumbers" function:
readNumbers(15, 18, 89, 639)
// Output:
// [ 15, 18, [ 89, 639 ] ]
ご覧のとおり、restパラメーターはarguments
オブジェクトと同じではありません。1つの違いは、RESTパラメーターが実数配列であることです。あなたのような方法でそれを反復することができmap()
、sort()
、reduce()
、forEach()
。arguments
オブジェクトでそれを試してください。もう一つの違いは内容です。
arguments
オブジェクトは、関数に渡されるすべての引数が含まれています。restパラメーターには、一致するパラメーターを持たない追加の引数のみが含まれます。したがって、1つのパラメーターとRESTパラメーターを持つ関数があるとします。3つの引数を渡すと、restパラメーターには最後の2つだけが含まれます。
arguments
オブジェクトは、他の一方で、すべての引数、最初に通常と同様に残りの部分を含んでいます。
// Create a function with normal and also rest parameter:
function readNumbers(num1, num2, ...nums) {
console.log('num1: ', num1)
console.log('num2: ', num2)
console.log('nums: ', nums)
}
// Invoke "readNumbers" function:
readNumbers(1, 3, 5, 7, 12)
// Output:
// 'num1: ' 1
// 'num2: ' 3
// 'nums: ' [ 5, 7, 12 ]
// Create a function with two parameters:
function readNumbers(num1, num2) {
console.log(arguments)
}
// Invoke "readNumbers" function:
readNumbers(1, 3, 5, 7, 12)
// Output:
// {
// '0': 1,
// '1': 3,
// '2': 5,
// '3': 7,
// '4': 12,
// length: 5,
// callee: ƒ readNumbers(),
// __proto__: {
// constructor: ƒ Object(),
// __defineGetter__: ƒ __defineGetter__(),
// __defineSetter__: ƒ __defineSetter__(),
// hasOwnProperty: ƒ hasOwnProperty(),
// __lookupGetter__: ƒ __lookupGetter__(),
// __lookupSetter__: ƒ __lookupSetter__(),
// isPrototypeOf: ƒ isPrototypeOf(),
// propertyIsEnumerable: ƒ propertyIsEnumerable(),
// toString: ƒ toString(),
// valueOf: ƒ valueOf(),
// toLocaleString: ƒ toLocaleString()
// }
// }
JavaScriptは、省略された引数をに設定しundefined
ます。フォールバック値を作成することで、これを回避できます。これは、デフォルトのパラメータを使用して実現できます。関数とそのパラメーターを定義するときは、代入演算子といくつかの値を使用して、各パラメーターのデフォルト値を定義できます。
後で関数を呼び出して必要な引数を指定しない場合、JavaScriptはundefined
。の代わりにデフォルト値を使用します。何らかの値を指定すると、JavaScriptはデフォルトの代わりにその値を使用します。
// Create a function with one parameter
// and set the default value of the parameter to "Anonymous":
function greetUser(username = 'Anonymous') {
return `Hello, ${username}!`
}
// Invoke the "greetUser" function without argument:
greetUser()
// Output:
// 'Hello, Anonymous!'
// Invoke the "greetUser" function with an argument:
greetUser('Timothy')
// Output:
// 'Hello, Timothy!'
関数のパラメーターと引数は混乱を招く可能性があります。この投稿によって、パラメーターと引数が何であるか、およびそれらがどのように異なるかを理解しやすくなることを願っています。また、この投稿が、argumentsオブジェクトとrestおよびdefaultパラメーターの使用方法を学ぶのに役立つことを願っています。
この記事が気に入ったら、今後の投稿を見逃さないように購読してください。
リンク: https://blog.alexdevero.com/function-parameters-arguments/