js函数与arguments存在的价值有多大?

663 阅读5分钟

函数与返回值

   function fn(n,m){//=>形参:入口
   //函数体
   var total =0; //=>total是私有变量
   total = n+m;
   console.log(total);
   }
   fn(10,20) ; //=>实参:给形参传递的具体值
   var a=12;
   fn(a,1===1?10:0);//实参一定是值,即使我们写的是变量或者表达式,也是把变量或者表达式计算的结果作为值传递给形参变量

创建函数,开辟一个堆内存空间,把函数体代码当作字符串存进来,把堆内存的地址复制给函数名

function fn(n,m){ //=>形参:入口 //函数体 var total =0; //=>total是私有变量 total = n+m; } fn(10,20) ; console.log(total); => VM55:8 Uncaught ReferenceError: total is not defined //total 是私有变量,我们无法在函数的外面直接获取这个值(闭包)

fn是函数体,函数本身 fn( )代表的是函数执行的值,就是return返回的值

/*
* 函数的入口:形参
* 函数的出口:返回值return
* 把函数运行的结果(或者函数体中的部分信息)拿到函数外面去使用
*/
 function fn(n,m){ 
   var total =0;  //=>total是私有变量
   total = n+m;
   return total; //=>并不是把total变量返回,而是返回的是变量存储的值,return返回的永远是个值
   }
  =>console.log(fn(1,2));
VM344:1 3
相当于:
var result = fn(1,2);
console.log(result);

如果当前函数没有return结果出来(或者return;啥也没有返回)函数执行在外面拿到的结果都是undefined

return还有一个重要的作用:

   function fn(n,m){
    var total=0;
    total=n+m;
    return total;   
}
console.log(fn(10));
=>NaN    //n为10,m为undefined
//如果n/m有一个没有传递值,我们返回零

需求如果n/m有一个没有传递值,我们返回零

   function fn(n,m){
   if (n === undefined || m === undefined) {
   return 0;
   //return 还有一个作用:类似循环中的bank,能够强制结果函数体中的代码执行
}
    var total=0;
    total=n+m;
    return total;   
}
console.log(fn(10));
=>0    //n为10,m为0
//如果n/m有一个没有传递值,我们返回零
//n === undefined 经常这样判断n的值是否为undefined,这种方式可以
//n == undefined 这种模式不好,因为null == undefined 也是相等的(==比较才不相等)
//type n == 'undefined' 真实项目中开发者更喜欢这种判断方式 

total=0; 0是有值的,值为0,从内存方面来说,undefinedye会在栈内存中占一个位置 total=null; 开发者更喜欢用null来作为初始值,null是空对象指针,是不占内存位置的

/*

  • 任意数求和:不管函数执行的时候,传递多少实参进来,我们都可以求和
  • 形参有局限性:我们需要具体的知道用户执行的时候传递实参数量,顺序等,才可以使用形参变量定义对应的入口

arguments及求和

  • arguments :函数内置实参的集合(内置:函数天生存在的机制,始终存在,不管是设置了实参,还是传递了实参) */
   function sum(n,m,z){
     console.log(argument);
     /*
     * arg是一个类数组(不是数组,不能直接使用数组中的方法)
     * 即使设置形参变量,形参该是什么,还是什么值,但是arg使用存储的是所有传递进来的实参,所有叫实参集合
     */
}
sum(10,20)
 =>M52:2 Arguments(2) [10, 20, callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: 10
1: 20
callee: ƒ sum(n,m,z) //存储的是当前函数本身
length: 2


/* 
* 把arg中存储的实参依次遍历,每遍历一个都累加起来,最后实现任意数求和
*/
function sum(){
   var total = null;
   for (var i=0;i<arguments.length; i++){
     var item = arguments[i]; //每一次遍历出来的实参值
     total += item; 
  }
  return total;
}
console.log(sum(10,20,30));

-> argument的callee的属性
function sum(n,m){
  console.log(arguments.callee===sum);
}
sum(10,20);
=>VM373:2 true

function sum(n,m){
  console.log(arguments.callee);
}
sum(10,20);
=>VM434:2 ƒ sum(n,m){
  console.log(arguments.callee);
}
undefined

实现任意数求和方法1

 /* 
* 把arg中存储的实参依次遍历,每遍历一个都累加起来,最后实现任意数求和
*/
function sum(){
   var total = null;
   for (var i=0;i<arguments.length; i++){
     var item = arguments[i]; //每一次遍历出来的实参值
     total += item; 
  }
  return total;
}
console.log(sum(10,20,30));
=>60
//如果传递字符串
console.log(sum(10,'20')) =>'1020'

实现任意数求和方法2

 /* 
* 把arg中存储的实参依次遍历,每遍历一个都累加起来,最后实现任意数求和
* 如果传递字符串,把字符串转为数字,然后累加
*/
function sum(){
   var total = null;
   for (var i=0;i<arguments.length; i++){
     var item = arguments[i]; //每一次遍历出来的实参值
     //1.不管item获取的事传递的啥,都先转换为数字类型 sum(10,'20','AA')
     item = Number(item);
     //2.如果当前的值是有效数字我们才累加,非有效数字直接跳过即可
     isNaN(item)?null:total += item;
      
  }
  return total;
}
//如果传递字符串,把字符串转为数字,然后累加
console.log(sum(10,'20','AA')) =>30

用es6实现

let sum=(...arg) => {
    arg = arg.filter(item => !isNaN(item));
    return eval(arg.join('+'));
};
console.log(sum(10,'20','AA'));
=>30

实名函数:有函数名 匿名函数:没有函数名

  • 函数表达式: 把函数当做值赋值给变量或者元素的事件
  • 自执行函数:创建和执行一起完成的
//函数表达式
   var fn = function () {

}
//匿名函数
oBox.onclick = function () {

}
//自执行函数
(function () {

})();
~function (){

}();
+function (){

}();
!function () {

}();