写文章不容易,点个赞呗兄弟 专一 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工做原理,源码版助于了解内部详情,让咱们一块儿学习吧 研究基于 Vue版本 【2.5.17】javascript
若是你以为排版难看,请点击 下面连接 或者 拉到 下面关注公众号也能够吧java
今天咱们解读 methods 的源码,其实 methods 挺简单的,因此就不打算出白话版了,可是 methods 里面让我从新认识到这一个重要的知识点,是我是我,可能大家已经掌握了哈哈闭包
<br> <br>app
methods 简单到什么程度呢,估计你用脚都能想获得函数
那么如今的问题怎么解答oop
"遍历 methods 这个对象,而后逐个复制到 实例上?"学习
没错,你猜对了,的确是逐个复制,简化源码是这么写的优化
function initMethods(vm, methods) { for (var key in methods) { vm[key] = methods[key] == null ? noop : bind(methods[key], vm); } }
<br>this
<br>
其实 methods 的固定做用域的惟一重点就是 bind 了,bind 相信你们也都用过
bind 是固定函数做用域的,说实在的,以前我还真不太用 bind 这个东西,就知道能够绑定做用域,我以为我会 call 和 apply 就好了,如今后悔了,发现用处太大了
调用 bind 会 返回 绑定做用域的函数,而这个函数直接执行时,做用域就已是固定了的
不像 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 了,颇有用哦,这个东西,你们务必要记住
<br> <br>
一、methods 会逐个复制到 实例上
二、methods 方法会使用 bind 绑定实例做用域,确保做用域不被修改