ES6學習筆記(6)----函數的擴展

来源:https://www.cnblogs.com/carolddz/archive/2018/03/14/8568992.html
-Advertisement-
Play Games

參考書《ECMAScript 6入門》http://es6.ruanyifeng.com/函數的擴展函數的預設值 : ES6可以為函數指定預設值(1)指定預設值的兩種方式 a.函數參數的預設值 function test(a = 0,b = 5){ return a+b; } test();//5 ...


參考書《ECMAScript 6入門》
http://es6.ruanyifeng.com/

函數的擴展

函數的預設值 : ES6可以為函數指定預設值

(1)指定預設值的兩種方式

  a.函數參數的預設值
  function test(a = 0,b = 5){
    return a+b;
  }
  test();//5 調用方法時,參數a,b都是undefined,可以使用預設值,因此返回5
  test(7);//7+5 = 12
  test(,10);//報錯 非尾參數設置了預設值,則調用函數時此參數無法忽略,忽略報錯;顯示傳入undefined,則觸發預設值
 
  在參數中定義了預設值的變數,代碼塊中不能再用let或const重新定義變數(let與const不允許在同一個作用域內重覆聲明同一個變數)
  function test3(a = 1){
    let a = 7;
    return a;
  }
  test3()//執行此方法時報錯(定義此方法test3時不報錯)Uncaught SyntaxError: Identifier 'a' has already been declared
  function test4(b = 'sdf'){
    const b = 'test4';
    return b;
  }
  test4()//執行此方法時報錯(定義此方法test4時不報錯)Uncaught SyntaxError: Identifier 'b' has already been declared
  function test5(c = 8){
    var c = 1;
    return c;
  }
  test5()//1 不報錯 let與const不允許在同一個作用域內重覆聲明同一個變數,而var可以,所以使用var重覆聲明c不報錯
 
  使用參數的預設值時,不可以在聲明同名參數
  function test6(a = 1, a, b){
    return a+b;
  }//函數定義時就報錯 Uncaught SyntaxError: Duplicate parameter name not allowed in this context
 
  b.對象的解構賦值預設值
  function test2({a = 1,b = 8}){
    return a+b;
  }
  test2({});//9此時參數是一個空對象,空對象里的屬性全是undefined, 所以函數可以使用參數的預設值
  test2({a:12,b:13});//25
  test2({a:15});//23
  test2();//此處使用的是對象的解構賦值預設值,如果傳入的參數不是對象,就無法讓對象的解構賦值預設值生效,報錯 Cannot destructure property `a` of 'undefined' or 'null'.
  //要解決此問題,可以將其轉化為進一步的參數預設值
  function test2({a = 2,b = 3} = {}){ //此處表示函數test2的預設參數是一個空對象,此空對象的屬性a的預設值是2,屬性b的預設值是3
    return a+b;
  }
  test2({});//5
  test2();//5
 
(2)指定預設值後length屬性將失真,已經制定預設值的參數以及位置在其後的參數都不參與length計數
  function test7(a,b,c,d){
    return a+b+c+d;
  }
  test7.length //4
  function test8(a,b = 0,c,d){
    return a+b+c+d;
  }
  test8.length //1 只計算了一個參數a,定義了預設值的參數b以及其後的c,d均不參與length計數
(3)參數預設值是不傳值的,如果參數預設值是一個表達式賦值,那每次都需要重新計算
(4)一旦設置了參數的預設值,函數進行聲明初始化時,參數會形成一個單獨的作用域(context)。等到初始化結束,這個作用域就會消失。這種語法行為,在不設置參數預設值時,是不會出現的。
(5)參數預設值用途:可用於提示某參數可省略(預設值設置成undefined)或者必須(預設值設置成可以返回異常提示語句的函數)

2.rest參數:rest參數是一個數組,length屬性不記錄rest參數。
  function test11(...restParams){
    return restParams;
  }
  test11(1,3,4,5,'qwe'); // [1,3,4,5,'qwe']
  test11.length; //0

3.函數的name屬性返回實際的函數名
  let f = function test12(){};
  f.name; // 'test12'
  Array.bind({}).name; // "bound Array"
4.箭頭函數
(1)箭頭函數的this始終是函數定義時的this,不是使用時的this
   function Timer(){
    this.s1 = 0;
    this.s2 = 0;
    setInterval(()=>this.s1++,1000);//箭頭函數中的this,指向Timer定義時的this,即this.s1 = 0;
    setInterval(function(){
    this.s2++;//常規寫法函數中的this,通常指向使用時的window/document全局變數,因此this.s2是NaN,而timer.s2始終是定義時的值。
    },1000);
   }
   var timer = new Timer();
   setTimeout(()=>console.log(timer.s1),3100);//3
   setTimeout(()=>console.log(timer.s2),3100);//0

(2)箭頭函數可以簡化函數寫法
   function insert(value){
    return {into : function(arr){
      return {afterValue : function(val){
        arr.splice(arr.index(val)+1,0,value);
        return arr;}
      }}}
   }
   let insert = (value) => {into : (arr) => ({afterValue : (val) => {arr.splice(arr.indexOf(val)+1,0,value);return arr;}})}

(3)如果箭頭函數右邊返回的是代碼塊,用{}括起來;如果箭頭函數右邊的是對象,則必須使用({})括起來。
   (a,b) => {return a+b}
   let test13 = (a,b) => ({name : a,value : b})
   test13("test",8); //{name : "test",value : 8}
(4)箭頭函數不能做構造函數,即不能使用new命令
   let test15 = (a,b) => a*b;
   new test15(); //報錯 Uncaught TypeError: test15 is not a constructor

5.雙冒號運算符:左邊是一個對象,右邊是一個函數
  object1 :: f1 //等同於f1.bind(object1)
  object2 :: f2(...restArr) //等同於 f2.apply(object2,restArr);
  ::f3 //等同於f3.bind(f3)
  ::f3(...restArr1) //等同於f3.apply(f3,restArr1);  
  如果雙冒號運算符的結果是一個對象,則可以鏈式使用

6.尾調用和尾調用優化
  尾調用:函數的最後一步調用了另外一個函數
  function test17(){
    return test18();//必須是最後一步調用此函數,而且是作為返回值返回
  }
  尾調用優化:函數A最後一步調用了另外一個函數B,且函數B執行過程中不需要使用到任何有關函數A里變數的操作,那麼在尾調用執行後,有關函數A的調用幀都可以刪除,只保留函數B的調用幀,這即是尾調用優化
  function A(a){
    a = a + 1;
    function B(b){
      console.log(b);
    }
    return B('this is a test')
  }
7.遞歸和尾遞歸
  遞歸:函數調用自身
  尾遞歸:函數尾調用自身
  常見遞歸:遍歷dom樹
  function traversal(node){
    //對node的處理
    if(node && node.nodeType === 1){
       console.log(node.tagName);
    }
    var i = 0, childNodes = node.childNodes,item;
    for(; i < childNodes.length ; i++){
        item = childNodes[i];
        if(item.nodeType === 1){
         //遞歸先序遍歷子節點
         traversal(item);//屬於尾遞歸
        }
    }
  }
  尾遞歸優化
 
  普通尾遞歸
  function sum(x){
    if(x === 1) {return 1};
    return x+sum(x - 1);//返回當前層次計算的x的值與下一子自身調用返回的值,因此當前的調用幀不能刪除
  }
  優化後的尾遞歸
  function sum(x,y){
    if(x === 1) {return y};
    return sum(x - 1,x+y);//執行後當前調用幀可以刪除,進入下一次自調用的新參數的調用幀
  }
  5,1-->4,5+1
  4,6-->3,5+1+4
  3,11-->2,5+1+4+3
  2,14-->1,5+1+4+3+2
  1,15--->15

8.尾逗號規則:ES6允許函數定義時尾參數帶逗號
function test16(p1,p2,p3,){}


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言:這是筆者學習之後自己的理解與整理。如果有錯誤或者疑問的地方,請大家指正,我會持續更新! AJAX 是 asynchronous javascript and XML 的簡寫,就是非同步的 javascript 和 XML。這一技術能夠向伺服器請求額外的數據而無須刷新整個頁面,會帶來更好的用戶體驗 ...
  • 1. ng-init 屬性: 2. ng-selected 屬性: <html><head></head><body> <!--<input type="text" ng-model="good.factory" title="{{good.factory}}">--> <select class= ...
  • 一、什麼是Promise Promise是對象,代表了一個函數最終可能的返回值或拋出的異常,就是用來非同步處理值的。 Promise是一個構造函數,自己身上有all、reject、resolve這幾個非同步方式處理值的方法,原型上有then、catch等同樣很眼熟的方法。 二、為什麼使用Promise ...
  • localstorage 是 HTML5 提供的在客戶端存儲數據的新方法,主要作用是將數據保存在客戶端中,並且數據是永久保存的,除非人為干預刪除。 localstorage 的局限 1、只有版本較高的瀏覽器中才支持 localstorage2、localStorage的值的類型限定為string類型 ...
  • 一.冒泡排序 原理:簡單來說就是相鄰兩個元素進行對比,按照你需要的排序方式(升序or降序)進行位置替換,替換時需要額外一個變數當作中間變數去暫存值。 總結步驟: 1、外迴圈是遍歷每個元素,每次都放置好一個元素; 2、內迴圈是比較相鄰的兩個元素,把大/小的元素交換到後面; 3、等到第一步中迴圈好了以後 ...
  • 一、內置一級構造函數Object(首字母大寫) 普通函數: 1)、不建議使用new關鍵字調用,否則就成為構造函數的調用了; 2)、可以用return語句返回值; 3)、函數內部不建議使用this關鍵字,函數裡面的this指向window,添加在this身上的屬性是全局屬性; 4)、函數命名以駝峰方式 ...
  • 今天換道題,新鮮出爐的 哇,這個題乍一看有點繞。我們可以簡單的分析一下 首先我們先註意下這段代碼主要做了什麼: 創建一個構造函數Model,利用Model去構建m對象 構造函數原型對象定義了兩個函數, say 和 getFullName m調用 say 函數 ,其中 say 函數內的 this 此時 ...
  • var s = 1; function test() { console.info(s); var s = 2; console.info(s); } test(); >>>undefined >>>2 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...