1. undefined处理
平时写未定义的时候都是直接用的if(a != undefined){}
这样写的坏处就是undefined如果被篡改了,或者重新赋过值,就回出现问题,例如var undefined = 1 ; if(a != undefined){}
怎么处理呢?
最常见的就是使用void 0
或者void(0)
来代替表示undefined
2. 迭代器iteratee
- 一个迭代器至少包括两部分:1. 被迭代的集合 2. 当前迭代过程
- 在underscore中,当前迭代过程是一个处理函数,称之为iteratee,它将对当前迭代元素进行处理(类似于我们平时自己封装的回调函数)
附上源码:
_.map = function(obj, iteratee, context) {
//生成不同功能迭代器,this指向的是context
var iteratee = cb(iteratee, context);
//分辨 obj是数组对象, 还是object对象
//obj取keys,数组取下标
var keys = !_.isArray(obj) && Object.keys(obj);
var length = (keys || obj).length;
var result = Array(length);
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
result[index] = iteratee(obj[currentKey], index, obj);
}
return result;
}
var cb = function(iteratee, context, count) {
if (iteratee == null) {
return _.identity;
}
if (_.isFunction(iteratee)) {
return optimizeCb(iteratee, context, count);
}
}
//optimizeCb优化迭代器
//void 0 就表示undefined
//如果没有context,就执行迭代器处理参数,有context就执行迭代器并且this指向context,然后依次处理函数
var optimizeCb = function(func, context, count) {
if (context == void 0) {
return func;
}
switch (count == null ? 3 : count) {
case 1:
return function(value) {
return func.call(context, value);
};
case 3:
return function(value, index, obj) {
return func.call(context, value, index, obj);
};
}
}
//默认迭代器
_.identity = function(value) {
return value;
}
这基本就是一个完整的迭代器了
怎么调用呢?
var obj = {name:'test'}
_.map([1,2,3],function(value,index,object){
return value*3
},obj)
- 调用map的方法,传入三个参数,第一个是数据,第二个是迭代器也就是要处理的函数,第三个是处理迭代器时引用的的对象
- iteratee会调用cb的方法,返回一个函数,如果迭代器未定义,返回一个identity,也就是原值返回,否则就回调用optimizeCb方法,返回optimizeCb的返回值。
- optimizeCb函数,返回的是对引用对象处理的迭代器函数
- 这样一来就返回给iteratee一个处理函数
- 处理传入的参数,是数组就获取下标,是对象就获取key,然后遍历,执行iteratee
迭代器的核心函数还是cb和optimizeCb函数
网友评论