数据类型_function_函数概论

概念

函数就是将某一段代码进行封装,并为这段代码起个名子,通过这个名子就可以调用这段代码,使用函数可以实现代码复用、便于修改;

函数声明

JavaScript 有三种声明函数的方法

[1]函数声明式

函数声明式是使用 function关键字 来定义函数; function关键字后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面

  • 语法

    • function 函数名(形参){
             
       // 函数体
      }
      
  • 举例说明

    • function paly(str){
             
        return `我最喜欢玩${
               str}`
      }
      
[2]函数表达式

采用变量赋值的方法,写一个匿名函数赋值给变量,这又称作函数表达式(因为等号右侧只能是表达式)

  • 语法

    • const 变量名 = function(){
              
        // 函数体 
      }
      
  • 举例说明

    • const play = function(str){
             
        return `我最喜欢玩${
               str}`
      }
      
  • 注意事项

    • 采用函数表达式声明函数时,function关键字后面不带有函数名。如果加上函数名,该函数名只在函数体内部有效,在函数体外部无效;

    • const play = function toplay(str){
             
        console.log('toplay1', toplay)
        return `我最喜欢玩${
               str}`
      }
      play() // f toplay(str){...}
      console.log('toplay2', toplay) // Error toplay is not defined
      
[3]使用构造函数声明函数

使用构造函数声明函数,参数中最后一个参数为函数体,除了最后一个参数之外的参数为函数的参数(不推荐使用);

  • 语法

    • new Function(形参···,函数体)
      
  • 示例

    • const paly = new Function('str','return `我最喜欢玩${str}`')
      console.log(paly('游戏')) // 我最喜欢玩游戏
      

函数调用

调用函数时,要使用圆括号运算符。圆括号之中,可以加入函数的参数;

函数名(实参)

函数提升

函数声明式具有函数提升->可以在声明之前调用

  • console.log('play', paly('游戏')) // play 我最喜欢玩游戏
    function paly(str){
         
      return `我最喜欢玩${
           str}`
    }
    
  • 上述代码等价于 将函数声明提升到当前作用域的最前面;

    • function paly(str){
             
        return `我最喜欢玩${
               str}`
      }
      console.log('play', paly('游戏'))
      

函数表达式没有函数提升,必须先声明后使用;
但是使用var定义变量过程中具有变量提升

  • console.log('play', play) // undefined
    console.log('play', play('游戏')) // Error  play is not a function
    var play = function(str){
         
      return `我最喜欢玩${
           str}`
    }
    
    • 上述代码等价于

    • var play
      console.log('play', play) // undefined
      console.log('play', play('游戏')) // Error  play is not a function
       play = function(str){
             
        return `我最喜欢玩${
               str}`
      }
      

使用let与const定义变量接收函数表达式则没有变量提升;

  • console.log('play', play) // Error Cannot access 'play' before initialization
    console.log('play', play('游戏'))
    let play = function(str){
         
      return `我最喜欢玩${
           str}`
    }
    
  • console.log('play', play) // Error Cannot access 'play' before initialization
    console.log('play', play('游戏'))
    const play = function(str){
         
      return `我最喜欢玩${
           str}`
    }
    
函数提升与变量提升的优先级

优先级:函数提升>变量提升;若是函数名与变量名相同,提升过程中不会被覆盖,但是重新赋值会被覆盖

  • 举例说明·

    • console.log(bar);  // function bar() { console.log(123); }
      console.log(bar()); // 123 undefined
      var bar = 456;
      function bar() {
             
        console.log(123); 
      }
      console.log(bar); // 456
      bar = 789;
      console.log(bar); //789
      console.log(bar()) // bar is not a function
      
      /*
      解析说明-[1]函数提升优先级大于变量提升,并且在提升过程中不会被变量提升覆盖
      var bar = function() {
        console.log(123); 
      }
      var bar
      console.log(bar);  
      console.log(bar()); 
      解析说明-[2]变量赋值会将函数覆盖
      bar = 456; 
      console.log(bar); 
      bar = 789;
      console.log(bar); 
      console.log(bar()) 
      */
      

函数重复声明

如果同一个函数被声明了多次,后一个函数就会覆盖前一个函数的声明;与此同时需要注意由于函数声明式具有函数提升,因此第一次声明在任何时候都是无用的!!!

function test(){
   
    console.log(111)
}
test() // 222
function test(){
   
    console.log(222)
}
test() // 222
  • 无论何时调用都是222

  • 上面代码等价于

    • function test(){
             
          console.log(111)
      }
      function test(){
             
          console.log(222)
      }
      test() // 222
      test() // 222
      

函数传值

函数涉及到的数据有两个方向:

  • 1、函数外向函数内传递->通过形参与实参可以实现将函数外的数据传递给函数内部。
  • 2、函数内向函数外传递->通过return关键字即可以实现将函数内的数据传递到函数的调用处
[1]参数

函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数;

function square(x) {
   
  return x * x;
}

square(2) // 4
square(3) // 9
  • 上面x就是square函数的形参,2、3就是square函数的实参;

形参与实参之间就是赋值的关系;

  • 若是简单数据类型,无论怎么修改不会影响原始值;
  • 若是复杂数据类型,相当于赋值的地址引用,修改属性/元素将会影响原始值
     // 简单类型
     function square(x) {
         
       x = 222
     }
     const num = 111
     square(num)
     console.log('num', num) // 111
     
     // 引用类型
     function square(x) {
         
       x.age = 22
     }
     const obj = {
         
         name:'chaochao',
         age:18
     }
     square(obj)
     console.log('obj', obj) // {name: 'chaochao', age: 22}
    

在函数调用过程中,实数是可以省略的,省略的参数的值就变为undefined

function square(x) {
   
  return x * x;
}

console.log(square()) // NaN
  • 但是,没有办法只省略靠前的参数,而保留靠后的参数。如果一定要省略靠前的参数,只有显式传入undefined;

      function f(a, b) {
         
        return a;
      }
      
      f( , 1) // SyntaxError: Unexpected token ,(…)
      f(undefined, 1) // undefined
    

    如果有同名的参数,则取最后出现的那个值;

    function f(a, a) {
         
      console.log(a);
    }
    
    f(1, 2) // 2
    
    function f(a, a) {
         
      console.log(a);
    }
    
    f(1) // undefined
    
arguments对象

由于 JavaScript 允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数。这就是arguments对象的由来;

arguments是一个对应于传递给函数的参数的伪数组

[1]除箭头函数外每个函数内部都有一个arguments对象

[2]作用是存储函数调用时传入的每一个参数(实参);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值