博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《javascript设计模式》笔记之第六章:方法的链式调用
阅读量:4598 次
发布时间:2019-06-09

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

这一章要实现的就是jQuery的那种链式调用,例子:

$(this).setStyle('color', 'green').show();
一:调用链的结构
首先我们来看一下最简单的$()函数的实现:
function $() {  var elements = [];  for (var i = 0, len = arguments.length; i < len; ++i) {    var element = arguments[i];    if (typeof element == 'string') {      element = document.getElementById(element);    }    if (arguments.length == 1) {      return element;    }    elements.push(element);  }  return elements;}
如果我们要实现$().method()这样的使用方法,想到应该就是$()函数有返回值,并且返回的是一个对象。要实现前面的所说的,最好的方法就是$()里面应该有个类可以让我们new一个对象出来,所以上面的代码就变成下面的样子:
(function() {  // Use a private class.  function _$(els) {    this.elements = [];    for (var i = 0, len = els.length; i < len; ++i) {      var element = els[i];      if (typeof element == 'string') {        element = document.getElementById(element);      }      this.elements.push(element);    }  }  // The public interface remains the same.  window.$ = function() {    return new _$(arguments);  };})();
此外我们的对象应该要有方法可以调用啊,那就定义在prototype上吧,然后代码就变成下面那样了:
(function() {  function _$(els) {    // ...  }  _$.prototype = {    each: function(fn) {      for ( var i = 0, len = this.elements.length; i < len; ++i ) {        fn.call(this, this.elements[i]);      }      return this;    },    setStyle: function(prop, val) {      this.each(function(el) {        el.style[prop] = val;      });      return this;    },    show: function() {      var that = this;      this.each(function(el) {        that.setStyle('display', 'block');      });      return this;    },    addEvent: function(type, fn) {      var add = function(el) {        if (window.addEventListener) {          el.addEventListener(type, fn, false);        }         else if (window.attachEvent) {          el.attachEvent('on'+type, fn);        }      };      this.each(function(el) {        add(el);      });      return this;    }  };  window.$ = function() {    return new _$(arguments);  };})();
到这里,我们就可以大概的使用一下了:
$('test-1', 'test-2').show().    setStyle('color', 'red').    addEvent('click', function(e) {      $(this).setStyle('color', 'green');    });
二:设计一个支持方法链式调用的JavaScript库
一般的js库里面都包含着事件、DOM、Ajax这几个重要的模块,那模仿一下:
Function.prototype.method = function(name, fn) {  this.prototype[name] = fn;  return this;};(function() {  function _$(els) {    // ...  }  /*    Events      * addEvent      * getEvent  */  _$.method('addEvent', function(type, fn) {    // ...  }).method('getEvent', function(e) {    // ...  }).  /*    DOM      * addClass      * removeClass      * replaceClass      * hasClass      * getStyle      * setStyle  */  method('addClass', function(className) {    // ...  }).method('removeClass', function(className) {    // ...  }).method('replaceClass', function(oldClass, newClass) {    // ...  }).method('hasClass', function(className) {    // ...  }).method('getStyle', function(prop) {    // ...  }).method('setStyle', function(prop, val) {    // ...  }).  /*    AJAX      * load. Fetches an HTML fragment from a URL and inserts it into an element.  */  method('load', function(uri, method) {    // ...  });  window.$ = function() {    return new _$(arguments);  });})();
其实用的还是上面的方法。
不过,注意到最上面的几行代码了吗,我记得第一章说过,这样的话让添加prototype方法也使用链式调用玩起来了。。
还有,倒数第四行那里,我们总是把函数赋予给window.$,这样的话与一些使用$做命名空间的库是有冲突的,例如和jQuery有冲突~,那换命名空间吧,下面就实现一个安装器来方便改变命名空间:
Function.prototype.method = function(name, fn) {  // ...};(function() {  function _$(els) {    // ...  }  _$.method('addEvent', function(type, fn) {    // ...  })  // ...      window.installHelper = function(scope, interface) {    scope[interface] = function() {      return new _$(arguments);    }  };})();
上面代码的主要思想就是先不给任何全局变量赋值,只有调用installHelper绑定相应的命名空间之后才能使用。
使用方法如下:
installHelper(window, '$');$('example').show();
这样就等于把函数赋值给了window.$了。
三:使用回调从支持链式调用的方法获取数据
上面说的那些链式方法都是返回this的,如果方法本身要返回值了?那么和返回this不就冲突了吗?所以对于这种情况,我们要想出一种方法,那就是对于这种情况,我们传入一个回调函数,来调用返回来的数值,之后还是要返回this的~
例子:
window.API2 = window.API2 || {};API2.prototype = function() {  var name = 'Hello world';  // Privileged mutator method.  setName: function(newName) {    name = newName;    return this;  },  // Privileged accessor method.  getName: function(callback) {    callback.call(this, name);    return this;  }}();
上面代码只要看getName哪里就可以了,传入了一个回调函数,然后取出值来直接调用,之后还是返回this,就不破坏链式调用了。
上面代码的一个使用方法:
var o2 = new API2;o2.getName(console.log).setName('Meow').getName(console.log);
 

转载于:https://www.cnblogs.com/oadaM92/p/4358497.html

你可能感兴趣的文章
微软职位内部推荐-Software Engineer II
查看>>
20145219 《Java程序设计》第06周学习总结
查看>>
C# 执行bat文件并取得回显
查看>>
基于YOLO的Autonomous driving application__by 何子辰
查看>>
javascript中的继承
查看>>
iOS-如何写好一个UITableView
查看>>
如何在Objective-C中实现链式语法
查看>>
select2 下拉搜索控件
查看>>
WebAPI常见的鉴权方法,及其适用范围
查看>>
WPF实现QQ群文件列表动画(一)
查看>>
08. 删除重复&海量数据
查看>>
重新想象 Windows 8 Store Apps (71) - 其它: C# 调用 C++
查看>>
发布mvc遇到的HTTP错误 403.14-Forbidden解决办法
查看>>
jvm内存模型和内存分配
查看>>
4.循环结构
查看>>
记录一些好用的工具
查看>>
inner join on 三表查询四表查询5表查询不管多少表都可以
查看>>
超链接样式设置(去下划线)(转)
查看>>
[求助]linux同一目录可否挂载多个数据盘?
查看>>
restcontroller和controller区别
查看>>