写文章不容易,点个赞呗兄弟
专一 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工做原理,源码版助于了解内部详情,让咱们一块儿学习吧
研究基于 Vue版本 【2.5.17】
若是你以为排版难看,请点击 下面连接 或者 拉到 下面关注公众号也能够吧javascript
今天咱们解读 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 的固定做用域的惟一重点就是 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 绑定实例做用域,确保做用域不被修改