jQuery 2.0.3 源码分析之core(一)整体架构(2)


var aQuery = function(selector, context) {
       return  new aQuery.prototype.init();
}
aQuery.prototype = {
    init: function() {
        return this;
    },
    name: function() {
        return this.age
    },
    age: 20
}
aQuery.prototype.init.prototype = aQuery.prototype;
console.log(aQuery().name()) //20

百度借网友的一张图,方便直接理解:

fn解释下,其实这个fn没有什么特殊意思,只是jQuery.prototype的引用

分析二:链式调用

DOM链式调用的处理:

1.节约JS代码.

2.所返回的都是同一个对象,可以提高代码的效率

通过简单扩展原型方法并通过return this的形式来实现跨浏览器的链式调用。

利用JS下的简单工厂模式,来将所有对于同一个DOM对象的操作指定同一个实例。

这个原理就超简单了

复制代码 代码如下:


aQuery().init().name()
分解
a = aQuery();
a.init()
a.name()

把代码分解一下,很明显实现链式的基本条件就是实例this的存在,并且是同一个

复制代码 代码如下:


aQuery.prototype = {
    init: function() {
        return this;
    },
    name: function() {
        return this
    }
}

所以我们在需要链式的方法访问this就可以了,因为返回当前实例的this,从而又可以访问自己的原型了

复制代码 代码如下:


aQuery.init().name()

优点:节省代码量,提高代码的效率,代码看起来更优雅

最糟糕的是所有对象的方法返回的都是对象本身,也就是说没有返回值,这不一定在任何环境下都适合。

Javascript是无阻塞语言,所以他不是没阻塞,而是不能阻塞,所以他需要通过事件来驱动,异步来完成一些本需要阻塞进程的操作,这样处理只是同步链式,异步链式jquery从1.5开始就引入了Promise,jQuery.Deferred后期在讨论。

分析三:插件接口

jQuery的主体框架就是这样,但是根据一般设计者的习惯,如果要为jQuery或者jQuery prototype添加属性方法,同样如果要提供给开发者对方法的扩展,从封装的角度讲是不是应该提供一个接口才对,字面就能看懂是对函数扩展,而不是看上去直接修改prototype.友好的用户接口,

jQuery支持自己扩展属性,这个对外提供了一个接口,jQuery.fn.extend()来对对象增加方法

从jQuery的源码中可以看到,jQuery.extend和jQuery.fn.extend其实是同指向同一方法的不同引用

复制代码 代码如下:


jQuery.extend = jQuery.fn.extend = function() {

jQuery.extend 对jQuery本身的属性和方法进行了扩展

jQuery.fn.extend 对jQuery.fn的属性和方法进行了扩展

通过extend()函数可以方便快速的扩展功能,不会破坏jQuery的原型结构

jQuery.extend = jQuery.fn.extend = function(){...}; 这个是连等,也就是2个指向同一个函数,怎么会实现不同的功能呢?这就是this 力量了!

针对fn与jQuery其实是2个不同的对象,在之前有讲述:

jQuery.extend 调用的时候,this是指向jQuery对象的(jQuery是函数,也是对象!),所以这里扩展在jQuery上。
    而jQuery.fn.extend 调用的时候,this指向fn对象,jQuery.fn 和jQuery.prototype指向同一对象,扩展fn就是扩展jQuery.prototype原型对象。
    这里增加的是原型方法,也就是对象方法了。所以jQuery的api中提供了以上2中扩展函数。

extend的实现

复制代码 代码如下:


jQuery.extend = jQuery.fn.extend = function() {
    var src, copyIsArray, copy, name, options, clone,
        target = arguments[0] || {},    // 常见用法 jQuery.extend( obj1, obj2 ),此时,target为arguments[0]
        i = 1,
        length = arguments.length,
        deep = false;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgpfzg.html