// 上一篇中出现的未曾重写的代码,这一篇中不再重复
var Observer = function Observer(value) {
this.value = value;
this.dep = new Dep();
// 如果是数组,则遍历所有元素
if(Array.isArray(value)) {
this.observeArray(value);
} else {
this.walk(value);
}
};
Observer.prototype.observeArray = function observeArray(items) {
// 遍历数组所有元素,对单个元素进行 getter、setter 绑定
for (var i = 0, l = items.length; i < l; i++) {
observe(items[i]);
}
};
function def(obj, key, val, enumerable) {
Object.defineProperty(obj, key, {
value: val,
// 转变为 boole 值,如果不传参,转为 false
enumerable: !!enumerable,
writable: true,
configurable: true
});
}
var hasProto = '__proto__' in {};
var augment = hasProto ? protoAugment : copyAugment;
function protoAugment(target, src) {
target.__proto__ = src;
}
function copyAugment(target, src, keys) {
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
def(target, key, src[key]);
}
}
var arrayPush = {};
(function(method){
var original = Array.prototype[method];
arrayPush[method] = function() {
// this 指向可通过下面的测试看出
console.log(this);
return original.apply(this, arguments)
};
})('push');
var testPush = []; testPush.__proto__ = arrayPush; // 通过输出,可以看出上面所述 this 指向的是 testPush // [] testPush.push(1); // [1] testPush.push(2);
var arrayProto = Array.prototype; var arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function(method) {
// 获取原始的数组操作方法
var original = arrayProto[method];
// 在 arrayMethods 上新建属性 method,并为 method 指定值(函数)
// 即改写 arrayMethods 上的同名数组方法
def(arrayMethods, method, function mutator() {
var arguments$1 = arguments;
var i = arguments.length;
var args = new Array(i);
// 将伪数组 arguments 转变为数组形式
// 为何不用 [].slice.call(arguments)?
while(i--) {
args[i] = arguments$1[i];
}
var result = original.apply(this, args);
// 因 arrayMethods 是为了作为 Observer 中的 value 的原型或者直接作为属性,所以此处的 this 一般就是指向 Observer 中的 value
// 当然,还需要修改 Observer,使得其中的 value 有一个指向 Observer 自身的属性,__ob__,以此将两者关联起来
var ob = this.__ob__;
// 存放新增的数组元素
var inserted;
// 对几个可能有新增元素的方法单独考虑
switch(method) {
case 'push':
inserted = args;
break;
case 'unshift':
inserted = args;
break;
case 'splice':
// splice 方法第三个参数开始才是新增的元素
inserted =args.slice(2);
break;
}
if(inserted) {
// 对新增元素进行 getter、setter 绑定
ob.observerArray(inserted);
}
// 触发方法
ob.dep.notify();
return result;
});
};
var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
var Observer = function Observer(value) {
this.value = value;
this.dep = new Dep();
def(value, '__ob__', this);
// 如果是数组,则遍历所有元素
if(Array.isArray(value)) {
var argument = hasProto ? protoAugment : copyAugment;
argument(value, arrayMethods, arrayKeys);
this.observeArray(value);
} else {
this.walk(value);
}
};
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有