vue.js源码学习分享(九)
/* */ var arrayKeys = Object.getOwnPropertyNames(arrayMethods);//获取arrayMethods的属性名称 /**
* By default, when a reactive property is set, the new value is//默认情况下,当一个响应的属性被设置,新的值也转换成响应的。然而当经过向下支撑时,我们不想促使转换,因为这值也许是一个嵌套值在一个冻结的数据结构,转换它时将会失去最优化
* also converted to become reactive. However when passing down props,
* we don't want to force conversion because the value may be a nested value
* under a frozen data structure. Converting it would defeat the optimization.
*/
var observerState = {
shouldConvert: true,
isSettingProps: false
}; /**
* Observer class that are attached to each observed//观察者类被绑定到每一个观察对象,一旦绑定,这个观察者使目标对象的属性键转换到getter/setter方法,收集依赖和发送的更新
* object. Once attached, the observer converts target
* object's property keys into getter/setters that
* collect dependencies and dispatches updates.
*/
接下来是最关键的一部分
var Observer = function Observer (value) {
this.value = value;
this.dep = new Dep();
this.vmCount = 0;
def(value, '__ob__', this);//给value定义一个‘——ob——’属性,属性的值为这个Observer对象
if (Array.isArray(value)) {//判断是不是一个数组
var augment = hasProto
? protoAugment
: copyAugment;
augment(value, arrayMethods, arrayKeys);
this.observeArray(value);
} else {
this.walk(value);
}
}; /**
* Walk through each property and convert them into//walk方法穿过每一个属性并且把他们转换到getter或者setter方法。这个方法应当仅在value的类型为对象时候调用
* getter/setters. This method should only be called when
* value type is Object.
*/
Observer.prototype.walk = function walk (obj) {
var keys = Object.keys(obj);//获取对象的每个键
for (var i = 0; i < keys.length; i++) {
defineReactive$$1(obj, keys[i], obj[keys[i]]);
}
}; /**
* Observe a list of Array items.//观察一个数组项目的列表
*/
Observer.prototype.observeArray = function observeArray (items) {
for (var i = 0, l = items.length; i < l; i++) {
observe(items[i]);
}
}; // helpers /**
* Augment an target Object or Array by intercepting//增加一个目标对象或者数组通过用__proto__截取原型链
* the prototype chain using __proto__
*/
function protoAugment (target, src) {
/* eslint-disable no-proto */
target.__proto__ = src;
/* eslint-enable no-proto */
} /**
* Augment an target Object or Array by defining
* hidden properties.//增大一个目标对象或者数组通过定义隐藏的属性
*/
/* istanbul ignore next */
function copyAugment (target, src, keys) {
for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i];
def(target, key, src[key]);
}
} /**
* Attempt to create an observer instance for a value,//尝试创建一个观察者实例化一个值
* returns the new observer if successfully observed,//返回一个新的观察者如果成功被观察
* or the existing observer if the value already has one.//如果值已经有一个了则返回存在的观察者
*/
function observe (value, asRootData) {
if (!isObject(value)) {//如果value不是对象,那么就到此结束
return
}
var ob;
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
ob = value.__ob__;
} else if (
observerState.shouldConvert &&
!isServerRendering() &&
(Array.isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
ob = new Observer(value);
}
if (asRootData && ob) {
ob.vmCount++;
}
return ob
} /**
* Define a reactive property on an Object.//定义一个响应的属性在一个对象上
*/
function defineReactive$$1 (
obj,
key,
val,
customSetter
) {
var dep = new Dep(); var property = Object.getOwnPropertyDescriptor(obj, key);
if (property && property.configurable === false) {
return
} // cater for pre-defined getter/setters//满足预定义的 getter/setters
var getter = property && property.get;
var setter = property && property.set; var childOb = observe(val);
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
var value = getter ? getter.call(obj) : val;
if (Dep.target) {
dep.depend();
if (childOb) {
childOb.dep.depend();
}
if (Array.isArray(value)) {
dependArray(value);
}
}
return value
},
set: function reactiveSetter (newVal) {
var value = getter ? getter.call(obj) : val;
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
/* eslint-enable no-self-compare */
if ("development" !== 'production' && customSetter) {
customSetter();
}
if (setter) {
setter.call(obj, newVal);
} else {
val = newVal;
}
childOb = observe(newVal);
dep.notify();
}
});
} /**
* Set a property on an object. Adds the new property and
* triggers change notification if the property doesn't
* already exist.
*/
function set (obj, key, val) {
if (Array.isArray(obj)) {
obj.length = Math.max(obj.length, key);
obj.splice(key, 1, val);
return val
}
if (hasOwn(obj, key)) {
obj[key] = val;
return
}
var ob = obj.__ob__;
if (obj._isVue || (ob && ob.vmCount)) {
"development" !== 'production' && warn(
'Avoid adding reactive properties to a Vue instance or its root $data ' +
'at runtime - declare it upfront in the data option.'
);
return
}
if (!ob) {
obj[key] = val;
return
}
defineReactive$$1(ob.value, key, val);
ob.dep.notify();
return val
} /**
* Delete a property and trigger change if necessary.
*/
function del (obj, key) {
if (Array.isArray(obj)) {
obj.splice(key, 1);
return
}
var ob = obj.__ob__;
if (obj._isVue || (ob && ob.vmCount)) {
"development" !== 'production' && warn(
'Avoid deleting properties on a Vue instance or its root $data ' +
'- just set it to null.'
);
return
}
if (!hasOwn(obj, key)) {
return
}
delete obj[key];
if (!ob) {
return
}
ob.dep.notify();
} /**
* Collect dependencies on array elements when the array is touched, since
* we cannot intercept array element access like property getters.
*/
function dependArray (value) {
for (var e = (void 0), i = 0, l = value.length; i < l; i++) {
e = value[i];
e && e.__ob__ && e.__ob__.dep.depend();
if (Array.isArray(e)) {
dependArray(e);
}
}
}
vue.js源码学习分享(九)的更多相关文章
- vue.js源码学习分享(一)
今天看了vue.js源码 发现非常不错,想一边看一遍写博客和大家分享 /** * Convert a value to a string that is actually rendered. *转换 ...
- vue.js源码学习分享(七)
var _Set; /* istanbul ignore if */ if (typeof Set !== 'undefined' && isNative(Set)) { // use ...
- vue.js源码学习分享(六)
/* */ /* globals MutationObserver *///全局变化观察者 // can we use __proto__?//我们能用__proto__吗? var hasProto ...
- vue.js源码学习分享(八)
/* */ var uid$1 = 0; /** * A dep is an observable that can have multiple * directives subscribing() ...
- vue.js源码学习分享(五)
//配置项var config = { /** * Option merge strategies (used in core/util/options)//选项合并策略 */ optionMerge ...
- vue.js源码学习分享(四)
/** * Generate a static keys string from compiler modules.//从编译器生成一个静态键字符串模块. */ function genStaticK ...
- vue.js源码学习分享(三)
/** * Mix properties into target object.//把多个属性插入目标的对象 */ function extend (to, _from) { for (var key ...
- vue.js源码学习分享(二)
/** * Check if value is primitive//检查该值是否是个原始值 */ function isPrimitive (value) { return typeof value ...
- Vue.js 源码学习笔记
最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些.那么,就让我来吧:) 程序 ...
随机推荐
- cocos2x (c++/lua) spine 文件的预加载
在之前,笔者写过一编博客,通过lua在加载场景加载spineAnimation动画精灵,保存在table中,然后在游戏中创建动画精灵时,提取加载好的spineAnimaiton中的 spSkeleto ...
- C++内存管理(effective c++ 04)
阅读effective c++ 04 (30页) 提到的static对象和堆与栈对象.看了看侯老师的内存管理视频1~3.有点深. 了解一下. 目录 1 内存管理 1.1 C++内存管理详解 1.1.1 ...
- 【前端_js】Json对象和Json字符串的区别
转载1: Json对象和Json字符串的区别 转载2: JSON字符串与JSON对象的区别
- 水题:UVa133-The Dole Queue
The Dole Queue Time limit 3000 ms Description In a serious attempt to downsize (reduce) the dole que ...
- JVM执行子系统探究——类文件结构初窥
类文件(.class)是搞java的都非常熟悉的文件,一般我们在编写java之后文件之后,首先通过javac工具生成.class类字节码文件,而后在执行程序的时候由虚拟机加载执行.那么为什么要生成.c ...
- python算法-排列组合
排列组合 一.递归 1.自己调用自己 2.找到一个退出的条件 二.全排列:针对给定的一组数据,给出包含所有数据的排列的组合 1:1 1,2:[[1,2],[2,1]] 1,2,3:[[1,2,3],[ ...
- selenium - Js处理滚动条操作
# 11.Js处理滚动条操作 driver.execute_script('arguments[0].scrollIntoView();',target) target 为find_element_b ...
- wordpress 获取站点的所有链接
<?php include "wp-load.php"; $posts = new WP_Query('post_type=any&posts_per_page=-1 ...
- 九度oj 题目1376:最近零子序列
题目描述: 给定一个整数序列,你会求最大子串和吗?几乎所有的数据结构与算法都会描述求最大子串和的算法.今天让大家来算算最近0子串和,即整数序列中最接近0的连续子串和.例如,整数序列6, -4, 5, ...
- xtrabackup: error: last checkpoint LSN (3409281307) is larger than last copied LSN (3409274368). #2
1.错误发生场景:使用2.4.1版本的xtrabackup工具进行全备,备份日志中报出此错误2.知识要点:MySQL中,redo 日志写进程会在三种条件下被触发从log buffer中写日志到redo ...