2018W23 學(xué)習(xí)筆記

這周因?yàn)榕笥呀Y(jié)婚幫忙的緣故,學(xué)習(xí)的內(nèi)容明顯下降了不少。所以,等明天開始,得需要恢復(fù)之前每天學(xué)習(xí)的強(qiáng)度。

本周的學(xué)習(xí)共分為3塊:

  1. ES6基礎(chǔ)學(xué)習(xí)與深入;
  2. Vue源碼閱讀;
  3. 前端進(jìn)階班的預(yù)習(xí);
    下面我們按照上面模塊一起去看一下本周我到底獲得了哪些收貨。

1.ES6學(xué)習(xí)

閱讀完成《深入理解ES6》的第三章。第三章主要講述的是函數(shù)的ES6新特性。
我們都知道ES6是ES5的加強(qiáng)與補(bǔ)充,是為了解決ES5中某些遺留問題而提出的新的解決方案或者加強(qiáng),所以順著這個(gè)思路,我就去做了這樣的筆記。

1.1 ES6函數(shù)新特性

在ES6中,針對(duì)函數(shù),補(bǔ)充了如下的一些特性:

  • 參數(shù)默認(rèn)值
  • 使用不具名函數(shù)
  • 函數(shù)構(gòu)造器增強(qiáng)
  • 擴(kuò)展運(yùn)算符
  • 函數(shù)的雙重用途
  • 塊級(jí)函數(shù)
  • 箭頭函數(shù)
  • 尾調(diào)用優(yōu)化
1.1.1 參數(shù)默認(rèn)值

傳統(tǒng)的ES5設(shè)置函數(shù)默認(rèn)值需要逐個(gè)對(duì)參數(shù)進(jìn)行設(shè)置,所以代碼量非常多,而且對(duì)于JS這種不限制函數(shù)參數(shù)的行為其擴(kuò)展性也很差。所以ES6在ES5的基礎(chǔ)上增加了參數(shù)默認(rèn)值的特效,其語法如下:

    function demo(url, timeout = 2000 , fn = function()
        {console.log('do it')
    })

值得注意的是,我們可以向參數(shù)傳遞Undefined值來使用默認(rèn)的參數(shù)值,以上面函數(shù)為例,

      demo('http://www.baidu.com',undefined,fn)

這樣就可以繼續(xù)使用第二個(gè)參數(shù)的默認(rèn)值了。

初次之外,還涉及到了2個(gè)比較“冷門的問題”:

  1. ES6參數(shù)默認(rèn)值是如何影響argument對(duì)象;
  2. 參數(shù)默認(rèn)值的暫時(shí)性死區(qū);

1.1.2 使用不具名函數(shù)

ES5的不具名的arguments對(duì)象在實(shí)際使用過程中會(huì)有很多的限制。在書中,就通過underscorejs庫中Pick函數(shù)的講解來說出arguments的不足。

  // 復(fù)制特定對(duì)象的特定屬性
  function pick(object) {
    let result = Object.create(null);
    // 從第二個(gè)參數(shù)開始處理
    for (let i = 1, len = arguments.length; i < len; i++) {
      result[arguments[i]] = object[arguments[i]];
  }
    return result;
  }

  1. 雖然該函數(shù)能處理多個(gè)函數(shù),但是在函數(shù)的表現(xiàn)上則完全看不出;
  2. 函數(shù)的第一個(gè)參數(shù)是選中的目標(biāo)對(duì)象,從第二個(gè)開始才是需要復(fù)制的屬性。

因此ES6引入了剩余參數(shù)這個(gè)概念,使用剩余函數(shù)對(duì)上述函數(shù)進(jìn)行改寫,則清晰和優(yōu)雅不少。

  function pick(object, ...keys) {
    let result = Object.create(null);
    for (let i = 0, len = keys.length; i < len; i++) {
    result[keys[i]] = object[keys[i]];
    }
    return result;
}

通過引入剩余參數(shù),我們就可以知道函數(shù)可以處理多余的函數(shù)。并且這與包含所有參數(shù)的arguements不同,我們可以單獨(dú)對(duì)剩余函數(shù)進(jìn)行處理。當(dāng)然剩余函數(shù)也有剩余的不足,主要有以下兩點(diǎn):

  1. 剩余參數(shù)必須要放在最后面;
  2. 剩余參數(shù)放在setter函數(shù)中不可用,會(huì)報(bào)語法錯(cuò)誤。

1.1.3 函數(shù)構(gòu)造器

作者聲稱,函數(shù)默認(rèn)值加上剩余函數(shù)加強(qiáng)了函數(shù)構(gòu)造器的能力,但是,在實(shí)際工作中,筆者覺得函數(shù)構(gòu)造器的用處并不多。


1.2.4 擴(kuò)展運(yùn)算符

剩余參數(shù)是將多個(gè)參數(shù)添加進(jìn)數(shù)組,而擴(kuò)展運(yùn)算符則是將數(shù)組的元素分成單個(gè)的元素,類似于split的功能。它主要的目的是代替apply。其使用場(chǎng)景如下:

   let values = [1,8,3];
  // ES5版本
  Math.max.apply(Math, values);

   // ES6版本
  Math.max(...values);

在之前的ES5版本中,要實(shí)現(xiàn)求一個(gè)數(shù)組的最大數(shù),需要使用apply去更改上下文的執(zhí)行環(huán)境,而有了擴(kuò)展運(yùn)算符之后,則輕松很多,并且從語義化角度上來說,也清晰不少。


1.1.4 函數(shù)的雙重用途

在ES5中,函數(shù)是否調(diào)用new操作符則意味著不同的用途。沒有new操作符,它就是執(zhí)行函數(shù)體內(nèi)的代碼。而有了new,函數(shù)就會(huì)執(zhí)行內(nèi)部[[ constructor]]方法,構(gòu)建一個(gè)對(duì)象。所以這就是函數(shù)的雙重用途的意思。
在ES5中,判斷函數(shù)是否調(diào)用了new操作,最簡(jiǎn)單也是最流行的一種做法就是使用instanceof這個(gè)方法,但是,這個(gè)方法也有明顯的缺陷,開發(fā)者可以使用apply去改變函數(shù)執(zhí)行的上下文順序,從而使instanceof的執(zhí)行判斷出錯(cuò)。

function Person(name) {
    if (this instanceof Person) {
        this.name = name; // 使用 new
      } else {
          throw new Error("You must use new with Person.")
      }
     }  
      var person = new Person("Nicholas");
      var notAPerson = Person.call(person, "Michael"); // 奏效了!

因此在ES6中引入了new.target來彌補(bǔ)相關(guān)不足。

    function Person(name){
        if(typeof new.target != undefined){
            this.name =name;
        }else{
            throw new Error('must with new');
        }
    }

其底層原理是,在調(diào)用new 操作符時(shí),調(diào)用[[ constructor ]]方法,new.target才會(huì)生成,(否則為undefined)并且將this對(duì)象賦值為原構(gòu)造函數(shù)。


1.1.5 ES6箭頭函數(shù)

之前也學(xué)習(xí)過ES6箭頭函數(shù),但是沒有想到的是,ES6函數(shù)為了增強(qiáng)ES5函數(shù)的一些不足,竟然和傳統(tǒng)的函數(shù)有很多不一樣的特點(diǎn):

  1. 沒有this,super,arguments和new.target綁定;
  2. 箭頭函數(shù)不能作為構(gòu)造函數(shù),也就是說不能被new,也沒有prototype屬性;
  3. 不能更改this的指向(js深惡痛絕的this指向問題);
  4. 不能重復(fù)相同的參數(shù)命名。

這些特點(diǎn)是為了減少箭頭函數(shù)內(nèi)部的錯(cuò)誤與不確定性,為了js函數(shù)更好的運(yùn)行。


2. Vue源碼學(xué)習(xí)

主要是看了第500-900行的代碼,粗略地知道了Vue對(duì)數(shù)組的監(jiān)聽。

首先獲取數(shù)組的原型對(duì)象,在這個(gè)對(duì)象上有數(shù)組的方法。

    var arrProto = Array.prototype;

然后使用Object.create的方法創(chuàng)建了一個(gè)空對(duì)象,其中它的原型鏈上有數(shù)組方法的集合。

    var arrMethods = Object.create(arrProto);

創(chuàng)建一個(gè)數(shù)組方法的集合:

    var methodsToPatch = [
            'push',
            'pop',
            'shift',
            'unshift',
            'splice',
            'sort',
            'reverse'
        ];

最關(guān)鍵的一步:對(duì)arrMethods進(jìn)行構(gòu)建:

給arrMethods添加屬性

  1. 遍歷methodsToPatch,在回調(diào)函數(shù)中調(diào)用def函數(shù)給arrMethods添加方法相對(duì)應(yīng)的屬性
    methodsToPatch.forEach(method => {
            def(arrMethods, method, function mutator() {
                // 相關(guān)代碼第二步進(jìn)行解析
            })
        });

    function def(obj, key, val, enumerable) {
            Object.defineProperty(obj, key, {
                value: val,
                enumerable: !!enumerable,
                writable: true,
                configurable: true
            });
        }?

  1. muator函數(shù)的定義
       function mutator() {
            //定義args容器,并且獲取函數(shù)參數(shù)的長度
            var args = [],
                len = arguments.length;

            while (len--) args[len] = arguments[len]; //將類數(shù)組轉(zhuǎn)換成數(shù)組

            //這里的this指的就是arrMethods 調(diào)用arrMethods中的方法和參數(shù)
            var result = original.apply(this, args);

            //監(jiān)聽類 下面代碼就調(diào)用了它的notify和observeArray方法
            var ob = this.__ob__; 
            var inserted;

            //如果是push/unshift/splice方法 對(duì)inserted進(jìn)行賦值
            switch (method) {
                case 'push':
                case 'unshift':
                    inserted = args;
                    break;

                case 'splice':
                    inserted = args.splice(2);
                    break;
            }

            
            if (inserted) {
                ob.observeArray(inserted); //對(duì)傳入的參數(shù)進(jìn)行監(jiān)聽
            }

            ob.deep.notify(); //通知視圖發(fā)生變化

            return result;

        };  
    

3.課程進(jìn)階學(xué)習(xí)

這里總結(jié)性的語言就不寫了,拋出問題,測(cè)試一下是否能回答出:

  • 有哪3種為DOM元素注冊(cè)事件處理函數(shù)的方式?分別有什么限制和優(yōu)點(diǎn)?

  • Dom Event接口中哪些屬性和接口需要了解?

  • 如何自定義一個(gè)Event事件?請(qǐng)寫出一個(gè)demo;

  • JS事件的傳播是如何傳播的?

  • 簡(jiǎn)述下面代碼的執(zhí)行順序

        // html 
        <div id='outter'>
            <p id='inner'> click </p>
        </div>

        // js
        
        let outter = document.getElementById('outter');
        let inner = document.getElementById('inner');
        
        outter.addEventListener('click', function () {
            console.log('outter-true')
        }, true);
        inner.addEventListener('click', function () {
            console.log('inner-true')
        }, true);
        inner.addEventListener('click', function () {
            console.log('inner-false')
        }, false);
        outter.addEventListener('click', function () {
            console.log('outter-false')
        }, false);

  • 請(qǐng)解釋一下什么是JS事件代理?

  • 請(qǐng)簡(jiǎn)單地寫一下事件代理的demo;

  • 可以使用哪個(gè)事件來阻止事件的傳播?

  • util.callbackify這個(gè)API的作用是什么?

  • 回調(diào)函數(shù)中的第一個(gè)參數(shù)和第二個(gè)參數(shù)分別是什么?

  • 請(qǐng)寫出API的具體使用方法:將一個(gè)異步函數(shù)轉(zhuǎn)換為錯(cuò)誤回調(diào)優(yōu)先的函數(shù)

  • 回調(diào)函數(shù)中的 null 有什么意義么?

  • 回調(diào)函數(shù)中的錯(cuò)誤原因可以通過什么屬性獲?。?/p>

  • generator對(duì)象是什么?怎樣才能獲取到?

  • 請(qǐng)寫出generator最基本的語法;

  • 調(diào)用一個(gè)生成器函數(shù)會(huì)立即執(zhí)行函數(shù)體里面的語句么?

  • 發(fā)布/訂閱模式和觀察者的區(qū)別是什么?


梳理完本周學(xué)習(xí)的內(nèi)容,發(fā)現(xiàn)有很多都已經(jīng)忘了,不多說了,需要趕緊去復(fù)習(xí)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,557評(píng)論 0 13
  • 三,字符串?dāng)U展 3.1 Unicode表示法 ES6 做出了改進(jìn),只要將碼點(diǎn)放入大括號(hào),就能正確解讀該字符。有了這...
    eastbaby閱讀 1,670評(píng)論 0 8
  • 函數(shù)和對(duì)象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對(duì)于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,950評(píng)論 0 5
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡(jiǎn)單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,514評(píng)論 0 21
  • 你可能覺得,“戰(zhàn)略”這個(gè)詞你已經(jīng)非常熟悉了,很多地方都聽過無數(shù)次。但是,在很多情況下我們對(duì)”戰(zhàn)略“這個(gè)詞的理解是很...
    余子祥閱讀 328評(píng)論 0 1

友情鏈接更多精彩內(nèi)容