In depth understanding of JavaScript function parameters of recommendations

  • 2021-07-06 09:43:50
  • OfStack

Previous words

The parameters of javascript functions differ from those of functions in most other languages. A function doesn't care how many arguments it passes in, what data type the arguments are, or even can pass no arguments.

arguments

The function definition in javascript does not specify the type of the function parameter, and the function call does not do any type checking on the argument values passed in. In fact, the javascript function call does not even check the number of parameters passed in


function add(x){
return x+1;
}
console.log(add(1));//2
console.log(add('1'));//'11'
console.log(add());//NaN
console.log(add(1,2));//2

Same name formal parameter

In non-strict mode, a parameter with the same name can appear in a function, and only the last parameter with that name can be accessed


function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3

However, in strict mode, a syntax error is thrown when a homonym occurs


function add(x,x,x){
'use strict';
return x;
}
console.log(add(1,2,3));//SyntaxError: Duplicate parameter name not allowed in this context

Number of parameters

When the number of arguments is smaller than that specified by the function declaration, the remaining parameters are set to undefined values


function add(x,y){
console.log(x,y);//1 undefined
}
add(1);

Logic or operators are often used to set a reasonable default value for omitted parameters


function add(x,y){
y = y || 2;
console.log(x,y);//1 2
}
add(1);

[Note] In fact, using y 2 is not rigorous, and explicitly setting false values (undefined, null, false, 0,-0, '', NaN) will give the same result. Therefore, it should be set reasonably according to the actual scene

When the number of arguments is larger than the number of formal arguments, the remaining arguments cannot be obtained directly, and the arguments object mentioned soon needs to be used

The parameters in javascript are represented internally by an array. Function always receives this array, regardless of which parameters are contained in the array. This parameter array can be accessed in the function body through the arguments object to get every 1 parameter passed to the function. The arguments object is not an instance of Array, it is a class array object, and every one of its elements can be accessed using square bracket syntax


function add(x){
console.log(arguments[0],arguments[1],arguments[2])//1 2 3
return x+1;
}
add(1,2,3);

The length attribute of an arguments object shows the number of arguments, and the length attribute of a function shows the number of formal arguments


function add(x,y){
console.log(arguments.length)//3
return x+1;
}
add(1,2,3);
console.log(add.length);//2

Formal parameters are only convenient, but not necessary


function add(){
return arguments[0] + arguments[1];
}
console.log(add(1,2));//3

Object parameter

When a function contains more than three formal arguments, it can be a headache to remember the correct order of arguments in the call function


function arraycopy(/*array*/from,/*index*/form_start,/*array*/to,/*index*/to_start,/*integer*/length){
//todo
}

Parameters are passed in in the form of name/value pairs, so that the order of parameters is irrelevant. When defining a function, all the arguments passed in are written into a single object, and when calling, an object is passed in, and the name/value pair in the object is the real argument data needed


function easycopy(args){
arraycopy(args.from,args.form_start || 0,args.to,args.to_start || 0, args.length);
}
var a = [1,2,3,4],b =[];
easycopy({form:a,to:b,length:4});

Synchronization

When the number of formal parameters is the same, the value of arguments object and the value of corresponding formal parameters are kept in sync


function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3
0

[Note] Although the named parameter has the same value as the corresponding arguments object, it is not the same namespace. Their namespaces are independent, but their values are synchronous

However, in strict mode, the values of arguments objects and formal parameters are independent


function test(num1,num2){
'use strict';
console.log(num1,arguments[0]);//1 1
arguments[0] = 2;
console.log(num1,arguments[0]);//1 2
num1 = 10;
console.log(num1,arguments[0]);//10 2
}
test(1);

When a formal parameter does not have a corresponding argument, the value of the arguments object does not correspond to the value of the formal parameter


function test(num1,num2){
console.log(num1,arguments[0]);//undefined,undefined
num1 = 10;
arguments[0] = 5;
console.log(num1,arguments[0]);//10,5
}
test(); 

Internal attribute

"callee"

The arguments object has a property named callee, which is a pointer to the function that owns the arguments object

The following is the classical factorial function


function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3
3

However, the execution of the above function is tightly coupled to the function name at 1, and function decoupling can be eliminated by using arguments. callee


function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3
4

However, in strict mode, accessing this property throws an TypeError error


function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3
5

In this case, you can use a named function expression


function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3
6

"caller"

There are actually two caller attributes

caller for '1' function

The function's caller property holds the reference to the function that called the current function, and if the current function is called in global scope, its value is null


function outer(){
inner();
}
function inner(){
console.log(inner.caller);//outer(){inner();}
}
outer(); 
function inner(){
console.log(inner.caller);//null
}
inner();

In strict mode, accessing this property throws an TypeError error


function inner(){
'use strict';
//TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context
console.log(inner.caller);
}
inner();

"2" caller for arguments object

This attribute is always undefined, which is defined to distinguish arguments. caller from the function's caller attribute


function add(x,x,x){
return x;
}
console.log(add(1,2,3));//3
9

Similarly, in strict mode, accessing this property throws an TypeError error


function inner(x){
'use strict';
//TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context
console.log(arguments.caller);
}
inner(1);

Function overload

javascript functions cannot be overloaded in the traditional sense. In other languages, you can write two definitions for a function, as long as the signatures of the two definitions (the type and number of parameters accepted) are different

The javascript function is not signed because its parameters are represented by an array containing 0 or more values. Without a function signature, true overloading is impossible


// The following declaration overrides the previous declaration 
function addSomeNumber(num){
return num + 100;
}
function addSomeNumber(num){
return num + 200;
}
var result = addSomeNumber(100);//300

You can only mimic a method overload by checking the type and number of arguments in the passed-in function and reacting differently


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

Parameter passing

Arguments to all functions in javascript are passed by value. That is, copying values outside a function to parameters inside a function is just like copying values from one variable to another

'1' primitive type value

When you pass a value of a primitive type to a parameter, the passed value is copied to a local variable (named parameter or an element of an arguments object)


function addTen(num){
num += 10;
return num;
}
var count = 20;
var result = addTen(count);
console.log(count);//20 , no change 
console.log(result);//30

'2' Reference type value

When the value of the reference type is passed to the parameter, the address of this value in memory is copied to a local variable, so the change of this local variable is reflected outside the function


function setName(obj){
obj.name = 'test';
}
var person = new Object();
setName(person);
console.log(person.name);//'test'

When a formal parameter of a reference type is overridden inside a function, the variable refers to a local object. This local object will be destroyed immediately after the function is executed


function setName(obj){
obj.name = 'test';
console.log(person.name);//'test'
obj = new Object();
obj.name = 'white';
console.log(person.name);//'test'
}
var person = new Object();
setName(person); 

Related articles: