【Vue原理】Methods - 源碼版

寫文章不容易,點個讚唄兄弟
專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧
研究基於 Vue版本 【2.5.17】

若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧javascript

【Vue原理】Methods - 源碼版java

今天咱們解讀 methods 的源碼,其實 methods 挺簡單的,因此就不打算出白話版了,可是 methods 裏面讓我從新認識到這一個重要的知識點,是我是我,可能大家已經掌握了哈哈瀏覽器

在這裏插入圖片描述

methods 怎麼使用實例訪問?

methods 簡單到什麼程度呢,估計你用腳都能想獲得閉包

那麼如今的問題怎麼解答app

"遍歷 methods 這個對象,而後逐個複製到 實例上?"函數

沒錯,你猜對了,的確是逐個複製,簡化源碼是這麼寫的oop

function initMethods(vm, methods) {    
    for (var key in methods) {
        vm[key] = 
            methods[key] == null ? 
            noop : 
            bind(methods[key], vm);
    }
}

methods 如何固定做用域的

其實 methods 的固定做用域的惟一重點就是 bind 了,bind 相信你們也都用過學習

bind 是固定函數做用域的,說實在的,以前我還真不太用 bind 這個東西,就知道能夠綁定做用域,我以爲我會 call 和 apply 就好了,如今後悔了,發現用處太大了優化

調用 bind 會 返回 綁定做用域的函數,而這個函數直接執行時,做用域就已是固定了的this

不像 call 和 apply 這種一次性綁定做用域的 妖豔賤貨不一樣,這個貨一次綁定,終身受益啊

Vue 使用了 bind 去綁定 methods 方法,顯然是爲了不有些刁民會錯誤調用而報錯,索性直接固定做用域,並且考慮到 bind 有的瀏覽器不支持

因而寫了一個兼容方法,意思大概是這樣

一、bind 函數須要傳入做用域 context 和 函數 A

二、而後 閉包保存 這個 context,返回一個新函數 B

三、B 執行的時候,使用 call 方法 直接綁定 函數A 的做用域爲 閉包保存的 context

下面是 Vue bind 兼容的源碼,我建議你們把這個方法保存下來,尤大的東西,還不瞬間保存??

function polyfillBind(fn, ctx) {    
    function boundFn(a) {        
        var l = arguments.length;        
        return l ?
            (
                l > 1 ?
                fn.apply(ctx, arguments) :
                fn.call(ctx, a)
            ):
            fn.call(ctx)
    }
    boundFn._length = fn.length;    
    return boundFn
}

function nativeBind(fn, ctx) {    
    return fn.bind(ctx)

}

var bind = Function.prototype.bind ?
    nativeBind :
    polyfillBind;

Vue 使用 bind 以後,對咱們有什麼好處?

咱們調用 實例的方法,再也不每次都使用 實例去調用了

這樣子,有什麼好處呢,當屢次調用方法的話,使用局部變量保存以後,直接訪問局部變量能夠減小做用域鏈的檢索

methods:{
    test(){},
    getName(){        

        // 原本是這樣,屢次使用實例調用
        this.test() 
        this.test()    
       
        // 如今局部變量保存,這是優化點
        var test = this.test
        test()
        test()
    }
}

bind 綁定做用域強到沒法改變

在這裏插入圖片描述

舉栗子

function a(){    
    console.log(this)
}

var b={ name:1 }
var c = a.bind(b)
var d={
    c:c,    
    woqu:3434333
}
c()
d.c()

c 和 d.c 執行打印下面的結果
在這裏插入圖片描述
儘管使用 d 調用,做用域仍然是 b,簡直不要太強啊

講到這裏,methods 的精髓,就是 bind 了,頗有用哦,這個東西,你們務必要記住
在這裏插入圖片描述

總結

一、methods 會逐個複製到 實例上

二、methods 方法會使用 bind 綁定實例做用域,確保做用域不被修改

公衆號

相關文章
相關標籤/搜索