vue.js 源代码学习笔记 ----- core array.js

vue

/*

* not type checking this file because flow doesn't play well with

* dynamically accessing methods on Array prototype

*/

import { def } from '../util/index'

const arrayProto = Array.prototype

// Object.create 如果传入的是数组, 那么这个数组会被封装成一个对象,这个对象作为目标对象的__proto__属性缓存起来
// arrayMethods变成一个新对象, 通过 arrayMethods.__proto__.concat可以访问到原来的数组方法
// 这样就为 Object.definedProperty创造了条件

export const arrayMethods = Object.create(arrayProto)

/**

* Intercept mutating methods and emit events
这几个操作都会改变数组本身, 像slice不会改变数组本身, 这里没列出

*/

;[

'push',

'pop',

'shift',

'unshift',

'splice',

'sort',

'reverse'

]

.forEach(function (method) {

// cache original method 获得数组的原型方法, 并缓存

const original = arrayProto[method]

// arrayMethods 已经是一个对象, 带有__proto__属性, 下有各种原生数组方法

def(arrayMethods, method, function mutator () {

// avoid leaking arguments:

// http://jsperf.com/closure-with-arguments

let i = arguments.length

//作者看上去不喜欢用 [].slice.call , 具体没明白, 好像是slice获取arguments在有的浏览器会有参数泄露问题.

const args = new Array(i)
while (i--) {

args[i] = arguments[i]

}

//先执行原生的方法, 这里的this 就是指向 arrayMethods
const result = original.apply(this, args)

const ob = this.__ob__

let inserted

switch (method) {

case 'push':

inserted = args

break

case 'unshift':

inserted = args

break

case 'splice':
     //因为 siplce (0,2,a,b) 这里是要取得新插入的数组值 a b

inserted = args.slice(2)

break

}

//如果有新增的值, 监听一下

if (inserted) ob.observeArray(inserted)

// notify change 通知改变

ob.dep.notify()

return result

})

})

以上是 vue.js 源代码学习笔记 ----- core array.js 的全部内容, 来源链接: utcz.com/z/377024.html

回到顶部