博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript设计模式链式模式学习
阅读量:6606 次
发布时间:2019-06-24

本文共 5664 字,大约阅读时间需要 18 分钟。

  链式模式:通过在对象方法中将当前对象返回,实现对同一个对象多个方法的链式调用。从而简化对该对象的多个方法的多次调用,对该对象的多次引用。

  jquery是基于原型继承,每个原型下的方法都返回当前对象this,让当前对象一直在原型的最高层,这样就可以实现链式调用。我们来试着创建一个模仿的链式调用的方法.

var jquery = function(seletor, context) {        this.init(seletor, context)    }    jquery.fn = jquery.prototype = { //简化写法,再写query.prototype就能省点力气直接写jquery.fn        constructor: jquery,        length: 0,        init: function(seletor, context) {            //定义上下文简化版(*^__^*)            if (context instanceof jquery) { //判断上下文是否是jquery的实例                context = context[0]            } else {                context = context || document; //指定选择范围                //判断上下文是否为字符串                context = typeof context == 'string' ? querySelector(context) || context            }            this.context = context; //保存上下文            if (~seletor.indexOf('#')) { //判断补码是否为0,是则类,反之id选择                this.length = 1;                this[0] = context.querySelector(seletor);            } else { //类选择                var i = 0,                    selectArr = context.querySelectorAll(seletor),                    len = selectArr.length;                for (; i < len; i++) {                    this[i] = selectArr[i]                }                this.length = len            }            return this;        },        size: function() {            return this.length        }    }

  我们在页面上创建元素

1
2
var $cc = new jquery('#cc');console.log($cc) //=>jquery {0: div.cc, 1: div.cc, length: 2} console.log($cc.size()) //=>2

  但是我们发现跟真正的jquery有很大差别, 真正的jquery没有显示的new一个构造函数。我们试着修改上面的函数

var jquery = function(seletor, context) {  return new jquery.fn.init(seletor, context)}//然后执行var $cc = jquery('#cc');console.log($cc) //=>jquery {0: div.cc, 1: div.cc, length: 2} console.log($cc.size()) //=>$cc.size is not a function

  为什么会报错呢?因为这里new jquery.prototype.init,因为这里返回的this指向的是init.prototype,而不是jquery.prototype,init的prototype上并没有size这个方法。但是想一想,如果new jquery.prototype.init,返回的this指向jquery.prototype,那么不就能调用jquery.prototype的size方法吗?真正的jquery源码中是这样的解决这个问题.

jquery.fn.init.prototype = jquery.fn

  加上这句话再次运行就不会报错啦。

  真正的jquery有许多方法,有直接对jquery对象上挂载方法如:$.ajax,也有对选择器扩展的一些方法,如$(seletor).attr(),$(seletor).css...等等,也有许多jquery上的插件定义的方法。那么我们如何来拓展呢?在真正的jquery中,如果写过jquery插件或者了解过源码,那么你会知道,是通过extend这个方法来拓展jquery一些方法。我们来动手试试吧!

jquery.extend = jquery.fn.extend = function() {        var i = 1,            len = arguments.length,            target = arguments[0], //拷贝的目标对象            deep, //是否深拷贝标志            j;        /*只有一个参数*/        if (i == len) { //如$.extend({a:1}) 运行后得到$.a =1             target = this            i--        }        if (typeof arguments[0] == 'boolean') {            //如果深拷贝,如$.extend(true,{},{a:1,b:{c:2}},{d:3})            deep = true            i == 2            target = arguments[1] || {}        }        for (; i < len; i++) {            for (j in arguments[i]) {                var copy = arguments[i][j], //拷贝对象的值                    src = target[i]; //拷贝到目标对象的值                var type = {}.toString.call(copy)                    //深拷贝                if (deep && (type == '[object Object]' || type == '[object Array]')) {                    if (!Array.isArray(src)) {                        src = src || {}                    } else {                        src = src || []                    }                    target[j] = $.extend(deep, src, copy) //递归循环                } else if (copy != undefined) {                    target[j] = copy                }            }        }        return target    }

  让我们来动手试一试!运行效果

/*单个对象*/    var a = {        a: 1    }    jquery.extend(a)    console.log(jquery.a)    var b = {            b: 2,            c: {                d: 3            },        }        /*多个对象*/    var c = jquery.extend(a, b)    console.log(c)    c.c.d = 4    console.log(b.c.d)    var e = {            b: 2,            c: {                d: 3            },        }        /*深拷贝*/    var f = jquery.extend(true, a, e)    f.c.d = 4    console.log(e.c.d)

  运行成功后我们来为我们的jquery添加上方法,click,和attr

jquery.fn.extend({        on: (function(doc) {            if (doc.addEventListener) {                return function(type, fn) {                    var i = this.length - 1                    for (; i >= 0; i--) {                        this[i].addEventListener(type, fn, false)                    }                    return this                }            } else if (doc.attachEvent) {                return function(type, fn) {                    var i = this.length - 1;                    for (; i >= 0; i--) {                        this[i].attachEvent('on' + type, fn);                    }                    return this                }            } else {                return function(type, fn) {                    var i = this.length - 1;                    for (; i >= 0; i--) {                        this[i]['on' + type] = fn                    }                    return this                }            }        })(document),        attr: function() {            var arg = arguments,                len = arg.length;            if (len < 1) return false            if (len == 1) {                return this[0].getAttribute(arg[0])            } else if (len == 2) {                for (var i in arg[0]) {                    for (var j = this.length - 1; j >= 0; j--) {                        this[j].setAttribute(arg[0], arg[1])                    }                }                return this            }        }    })    jquery('.cc').on('click', function() {        console.log(this)    })    jquery('.cc').attr('class','aa')    console.log(jquery('.cc').attr('class'))

  以上就是javascript设计模式的链式模式的学习喔。以上皆为demo版jquery代码~

转载地址:http://tfbso.baihongyu.com/

你可能感兴趣的文章
Sql Server中不常用的表运算符之APPLY(1)
查看>>
【DM642】ICELL Interface—Cells as Algorithm Containers
查看>>
linux所有命令失效的解决办法
查看>>
力扣算法题—085最大矩阵
查看>>
svs 在创建的时候 上传文件夹 bin obj 这些不要提交
查看>>
mysql-用命令导出、导入表结构或数据
查看>>
Tinkphp
查看>>
EntityFrameworkCore 一对一 && 一对多 && 多对多配置
查看>>
How to temporally disable IDE tools (load manually)
查看>>
Vue.js学习 Item4 -- 数据双向绑定
查看>>
几种排序方式的java实现(01:插入排序,冒泡排序,选择排序,快速排序)
查看>>
server application unavailable
查看>>
浅谈尾递归的优化方式
查看>>
eclipse 的小技巧
查看>>
频率域滤波
查看>>
图片存储类型的种类、特点、区别
查看>>
GETTING UP AND RUNNING WITH NODE.JS, EXPRESS, JADE, AND MONGODB
查看>>
求二叉树第K层节点的个数
查看>>
关于cocos2d-x面试的问题
查看>>
MySQLs数据库建外键时自动跑到缩影处,真奇怪
查看>>