• JS—函数概述


     1.定义

    函数是对象,所以函数名就是指向函数对象的指针

    (1)函数声明

    function add (n,m){
      return n+m
    }

    (2)函数表达式

    let add = function(n, m) { 
     return n + m; 
    };

    函数表达式声明和函数声明方式几乎等价,不过还是有些不同的,如使用函数声明方式声明的函数:

    • 函数声明提升:函数声明会在任何代码执行之前先被读取并添加到执行上下文。

    (3)箭头函数

    let add = (n, m)=> { 
     return n + m; 
    }

    (4)Function构造函数

    这个构造函数接收任意多个字符串参数,最后一个参数始终会被当成函数体,而之前的参数都是新函数的参数
    let sum = new Function("num1", "num2", "return num1 + num2"); // 不推荐
    不推荐使用这种语法来定义函数,因为这段代码会被解释两次:
    • 第一次是把它当作常规ECMAScript代码
    • 第二次是解释传给构造函数的字符串

    这样会影响性能

    注意:

    • 如果是访问函数而不是调用函数,那就必须不带括号

    2.箭头函数——ES6

    任何可以使用函数表达式的地方,都可以使用箭头函数

    箭头函数简洁的语法非常适合嵌入函数的场景:
    1 let ints = [1, 2, 3]; 
    2 console.log(ints.map(function(i) { return i + 1; })); // [2, 3, 4] 
    3 console.log(ints.map((i) => { return i + 1 })); // [2, 3, 4]

    箭头函数的语法:

    • 如果只有一个参数,可以省略括号,多个参数必须加括号
      • let l = e =>{ return e }
    • 如果语句只有一条return语句,则可以省略return和函数体的{}
      • let l = e => e

    注意:

    • 箭头函数不能使用arguments、super、new.target
    • 也不能用作构造函数
    • 没有prototype属性

    3.函数名

    因为函数名就是指向函数的指针,所以它们跟其他包含对象指针的变量具有相同的行为。这意味着一个函数可以有多个名称,如下所示:
    1 function sum(num1, num2) { 
    2  return num1 + num2; 
    3 } 
    4 console.log(sum(10, 10)); // 20 
    5 let anotherSum = sum; 
    6 console.log(anotherSum(10, 10)); // 20 
    7 sum = null; 
    8 console.log(anotherSum(10, 10)); // 20 

    ES6的所有函数对象都会暴露一个只读的name属性,其中包含关于函数的信息。多数情况下,这个属性种保存的就是一个函数标识符,或者说是一个字符串化的变量名。如果是使用Function构造函数创建的,会被标识为"anonymous":

    1 function foo (){}
    2 let bar = function(){}
    3 let baz = ()=> {}
    4 
    5 console.log(foo.name);  // foo
    6 console.log(bar.name);  // bar
    7 console.log(baz.name);  // baz
    8 console.log((()=>{}).name);  // 空字符串
    9 console.log((new Function()).name);  // anonymous(匿名的)

    如果函数是一个获取函数(getter)、设置函数(setter),或者使用bind()实例化,那么标识符前面会加上一个前缀

     1 function foo() {} 
     2 console.log(foo.bind(null).name); // bound foo 
     3 let dog = { 
     4  years: 1, 
     5  get age() { 
     6  return this.years; 
     7  }, 
     8  set age(newAge) { 
     9  this.years = newAge; 
    10  } 
    11 } 
    12 let propertyDescriptor = Object.getOwnPropertyDescriptor(dog, 'age'); 
    13 console.log(propertyDescriptor.get.name); // get age 
    14 console.log(propertyDescriptor.set.name); // set age

    4.参数

    • JS不关心传入的参数个数,也不关心参数的数据类型。
    • 主要是因为 ECMAScript 函数的参数在内部表现为一个数组。函数被调用时总会接收一个数组,但函数并不关心这个数组中包含什么。如果数组中什么也没有,那没问题;如果数组的元素超出了要求,那也没问题。
      在使用 function 关键字定义(非箭头)函数时,可以在函数内部访问 arguments 对象,从中取得传进来的每个参数值。
    • arguments 对象是一个类数组对象(但不是 Array 的实例),因此可以使用中括号语法访问其中的
      元素(第一个参数是 arguments[0],第二个参数是 arguments[1])。而要确定传进来多少个参数,
      可以访问 arguments.length 属性。

     arguments对象的值始终会与对应的参数同步:

    1 function foo (n,m){
    2     arguments[1] = 12
    3     console.log( m );  // 12
    4     console.log( arguments[1] );  // 12
    5 }
    6 
    7 foo(1,2)

    注意:

    • 这并不意味这两者访问同一个内存地址,只会保持同步而已
    • 如果只传了一个参数,然后把 arguments[1]设置为某个值,那么这个值并不会反映到第二个命名参数。这是因为 arguments 对象的长度是根据传入的参数个数,而非定义函数时给出的命名参数个数确定的。
      • 1 function foo (n,m){
        2     arguments[1] = 12
        3     console.log( m );  // undefined
        4     console.log( arguments[1] );  // 12
        5 }
        6 
        7 foo(1)
    • JS种所有的参数都是按值传递的,不可能按引用传递参数。如果把对象作为参数传递,那么传递的值就是这个对象的引用
    • 严格模式下:
      • 给arguments[1]赋值不会影响m的值
      • 在函数种尝试重写arguments对象会导致语法错误(代码也不会执行)

    (1)箭头函数中的参数

     箭头函数中的参数无法通过arguments关键字访问,只能通过定义的命名参数访问

    1 let foo = (a,b)=>{
    2     console.log(arguments); 
    3 }
    4 
    5 foo(1,2)  // arguments is not defined

    5.没有重载

    ECMAScript 函数不能像传统编程那样重载。在其他语言比如 Java 中,一个函数可以有两个定义,只要签名(接收参数的类型和数量)不同就行。如前所述,ECMAScript 函数没有签名,因为参数是由包含零个或多个值的数组表示的。没有函数签名,自然也就没有重载。
    如果在 ECMAScript 中定义了两个同名函数,则后定义的会覆盖先定义的。
    1 function add(n){
    2     return n + 1
    3 }
    4 
    5 function add(n){
    6     return n + 2
    7 }
    8 
    9 console.log(add(1));  // 3

    模拟重载

    可以通过检查参数的类型和数量,然后执行不同的逻辑来模拟函数重载。

     1 function add(){
     2     if(arguments.length===1){
     3         return arguments[0]
     4     }else if(arguments.length==2){
     5         return arguments[0] + arguments[1]
     6     }
     7 }
     8 
     9 console.log(add(1));  // 1
    10 console.log(add(1,2));  // 3
  • 相关阅读:
    java中getResourceAsStream的问题 缓存
    springside 查询条件
    如何修改MySQL数据库引擎为INNODB
    获取用户真实 IP , 淘宝IP接口获得ip地理位置
    hibernate注解的CascadeType属性
    AssignmentHandler实现类用spring注入
    使用 jQuery dataTables
    转载:一致性 hash 算法( consistent hashing )
    转载:memcached完全剖析
    转载:连接MySQL数据库的两种方式介绍
  • 原文地址:https://www.cnblogs.com/codexlx/p/14334126.html
Copyright © 2020-2023  润新知