实现面向对象风格调用。

怎么实现面向对象风格调用呢?看一下我们的`_`函数的执行流程

var _ = function(obj){ 
        if(!(this instanceof _)){ // 此处为了实现面向对象风格调用,可以暂时不管
            return new _(obj);
        }
        this._wrapped = obj;
                //部分
    };
  1. 执行this instanceof _ ,this指向 window,window instanceof _为 false,!操作符取反,所以执行 new _(obj).

  2. new _(obj)中,this指向实例对象,window instanceof _ 为 true,取反后,代码接着执行。

  3. 执行 this._wrapped = obj, 函数执行结束。

  4. 总结,_([1,2,3])返回一个对象,为{_wrapped:[1,2,3]},该对象原型指向_.prototype

也即我们下一步目标:将_上的函数也挂到_.prototype上。

先把_上的函数获取一下吧。

functions()

 //将obj中所有函数均push进names中
    _.functions = function(obj){
        var names = [];
        for(var key in obj){
            if(_.isFunction(obj[key])){
                names.push(key);
            }
        }
        return names.sort();
    }

each()

一个源于jQuery的通用遍历方法,可用于遍历对象和数组 回调函数拥有两个参数:第一个为对象的成员或数组的索引,第二个为对应变量或内容 而且可以退出循环

//数组遍历
$.each([0,1,2],function(i,n){
        console.log('item # '+ i + ": " + n)
})
//item #0:0
//item #1:1
//item #2:2

//对象遍历
$.each({name;"John",lang:"JS"},function(i,n){
        console.log('name: '+ i + ",value: " + n)
})
//item name,value:John
//name:lang,value:JS

//退出循环
$.each([0,1,2,3,4,5],function(i,n){
        if(i>2){
                return false;
        }
        console.log("item #"+i+": " + n );
});
//item #0:0
//item #1:1
//item #2:2
_.each = function(obj,callback){
            var length,i = 0;

            //判断类数组对象和数组
            if(_.isArrayLike(obj)){
                    //为数组时
                    length = obj.length;
                    for(;i<length;i++){
                            //绑定this到当前遍历元素上,但是call对性能有一丢丢影响
                            if(callback.call(obj[i],obj[i],i) === false){
                                    //当回调函数返回false的时候,我们就中止循环
                                    break;
                            }
                    }
            }else{
                    //为对象时
                    for( i in obj){
                            if(callback.call(obj[i],obj[i],i) === false){
                                    break;
                            }
                    }
            }
            return obj;
    }
}

有了上面两个函数,我们就可以来写我们的主角 mixin()

回顾一下

因为_([1,2,3])返回一个为{_wrapped:[1,2,3]}的原型指向_.prototype的对象 为了调用_函数对象上的方法,我们要把_上的方法复制到_.prototype

 _.mixin = function(obj){
        _.each(_.functions(obj),function(name){
            var func = _[name] = obj[name];
            //原型链的函数在这里定义!调用的时候就会跳到这里了。
            _.prototype[name] = function(){
                var args = [this._wrapped];

                push.apply(args,arguments);

                return chainResult(this,func.apply(_,args)); //此处为了链式调用可以暂时不管
            };
        });

        return _;
    }

这里我们就可以用对象风格和函数风格来调用我们的函数库里的文件了,现在,我们来实现链式调用。

Last updated