函数

122 阅读4分钟

js学习之函数

(一)函数的创建

(1)将要封装的代码以字符串的形式传递给构造函数

var fun=new Function("console.log('hello');");
// 封装到函数中的代码不会立即执行
// 函数中的代码会在函数调用的时候执行
// 调用函数语法:函数对象()
fun();
// 当调用函数时,函数中封装的代码会按照顺序执行

在实际开发中很少使用构造函数来创建一个函数对象
注意:函数也是一个对象,使用typeof检查一个函数对象时,会返回function\

(2)使用函数声明来创建一个函数
function 函数名([形参1,形参2,形参n]){
}

function fun2(){
    console.log("hhh");
}
fun2();

(3) 使用函数表达式来创建函数
var 函数名=function([形参1,形参2,形参n]){ }

var fun3=function(){
    console.log("xxx");
};
fun3();

(二)函数的参数

(1)函数参数

  • 在调用函数时,可以在()中指定实参(实际参数),实参将会复制给函数中对应的形参
// 定义一个求和函数
function sum(a,b){
    console.log(a+b);
}
sum(1,2);
// 调用函数时解析器不会检查实参的类型,
// 所以要注意是否有可能会接收到非法的参数,如果有可能则需要对参数进行类型的检查
// 函数的实参可以是任意的数据类型
sum(123,"hello");
sum(true,false);
// 调用函数时,解析器也不会检查实参的数量
// 多余的实参不会被赋值
// 如果实参的数量少于形参的数量,则没有对应实参的形参将用undefined初始化
sum(123,456,"hello");
// sum(123);123+undefined 输出NaN
  • 实参还可以是一个对象,当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递
function sayhello(o){
    console.log("ws"+o.name+"age:"+o.age+"address:"+address);
}
    // 创建一个对象
    var obj={
        name:"wxy",
        age:18,
        address:"hzau"
    };
sayhello(obj);
  • 实参可以是一个函数
function fun(a){
    console.log("a="+a);
    a(obj);// 输出 ws:wxy age:18 address:hzau
}
fun(sayhello)      //输出 "a=function sayHello(o){
"console.log("ws:"+o.name+"age:"+o.age+"address:"+address);
}
fun(function(){alert("hello")});//输出  "a=function(){alert("hello")}"  将一个匿名函数传给形参

(2)默认参数

ES6 默认参数特性允许使用默认值初始化参数。 使用ES6默认参数特性将b默认为0

function sum(a, b = 0) { 
    console.log(b); // => 0
    return a+b;
} 
sum(1); // => 1 
sum(1, undefined); // => 1

注意,如果将undefined设置为第二个参数sum(1, undefined), b也将初始化为0

(三)函数的返回值

  • 使用return来设置函数的返回值
  • return后的值将会作为函数的执行结果返回
  • 可以定义一个变量来接收该结果
  • return后的语句都不会执行
  • 如果return语句后不跟任何值就相当于返回一个undefined
  • 如果函数中不写return,则也会返回undefined
  • return后可以跟任意类型的值
        function sum(a,b,c){
            var d=a+b+c;
            return d;
            alert("hello")
            return;
        }
        // 调用函数
        // 变量result的值就是函数的执行结果
        var result=sum(4,7,8);
        console.log("result="+result);

        var result=alert("hello");
        console.log("result="+result);
        // alert返回值也是undefined

(四)arguments对象

JS 函数的一个很好的特性是能够用可变参数调用同一个函数。这样可以使用 arguments 对象来获取传入的所有参数。

arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。

例如,对函数的参数求和:

function sumArgs() {
  console.log(arguments); // { 0: 5, 1: 6, length: 2 }
  let sum = 0;
  for (let i = 0; i < arguments.length; i++) {
    sum += arguments[i];
  }
  return sum;
}

sumArgs(5, 6); // => 11

arguments 是一个对应于传递给函数的参数的类数组对象。

箭头函数情况:箭头函数中没有arguments

const sumArgs = () => {
  console.log(arguments);
  return 0;
};

// throws: "Uncaught ReferenceError: arguments is not defined"
sumArgs();

(五)剩余参数

剩余参数语法允许们我将一个不定数量的参数表示为一个数组

function sumArgs(...numbers) {
  console.log(numbers); // [5, 6]
  return numbers.reduce((sum, number) => sum + number);
}

sumArgs(5, 6); // => 11

...numbers是一个剩余参数,它将成为一个由剩余参数组成的真数组[5,6]。由于numbers 是一个数组,所以就可以使用数组自有方法reduce(与类数组对象的参数相反)。

如果不想在剩余参数中收集所有参数,则可以组合常规参数剩余参数

function multiplyAndSumArgs(multiplier, ...numbers) {
  console.log(multiplier); // 2
  console.log(numbers);    // [5, 6]
  const sumArgs = numbers.reduce((sum, number) => sum + number);
  return multiplier * sumArgs;
}

multiplyAndSumArgs(2, 5, 6); // => 22

multiplier 是一个常规参数,它获取第一个参数的值。然后剩下的参数...numbers 接收剩余的参数。

(六)剩余参数和 arguments对象的区别

剩余参数和 arguments对象之间的区别主要有三个:

  • 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。

  • arguments对象不是一个真正的数组,而剩余参数是真正的 Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sortmapforEachpop

  • arguments对象还有一些附加的属性 (如callee属性)。