视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JavaScript链式调用实例浅析
2020-11-27 22:02:28 责编:小采
文档

本文实例分析了JavaScript链式调用。分享给大家供大家参考,具体如下:

$函数你已经很熟悉了。它通常返回一个html元素或一个html元素的集合,如下:

function$(){
 var elements = [];
 for(vari=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;
}

但是,如果把这个函数改造为一个构造器,把那些元素作为数组保存在一个实例属性中,并让所有定义在构造器函数的prototype属性所指对象中的方法都返回用以调用方法的那个实例的引用,那么它就具有了链式调用的能力。我首先需要把这个$函数改为一个工厂方法,它负责创建支持链式调用的对象。这个函数应该能接受元素数组形式的参数,以便我们能够使用与原来一样的公用接口。

(function(){
 //use private class
 function _$(els){
 this.elements = [];
 for(vari=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(){
 //use private class
 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;
 },
 show:function(prop,val){
 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;
 }
 };
 //The public interface remains the same.
 window.$ = function(){
 return new _$(arguments);
 }
})();

但是如果某个库或者框架已经定义了一个$函数,那么我们的这个库会将其改写,有个简单的办法是在源码中为$函数另去一个名字。但是如果你是从一个现有的库获得的源码,那么每次代码库获取更新的版本后 你都得重新改名字,因此这个方案并不是很好。好的解决办法就是像下面一样添加一个安装器:

window.installHelper = function(scope, interface) {
 scope[interface] = function() {
 return new _$(arguments);
 }
 };

用户可以这样去使用:

installHelper(window, '$');
$('example').show();

下面是一个更复杂的例子,它展示了如何把这种功能添加到一个事先定义好的命名对象中:

// Define a namespace without overwriting it if it already exists.
window.com = window.com || {};
com.example = com.example || {};
com.example.util = com.example.util || {};
installHelper(com.example.util, 'get');
(function() {
 var get = com.example.util.get;
 get('example').addEvent('click', function(e) {
 get(this).addClass('hello');
 });
})();

有时候把方法连起来并不是一个好主意。链式调用很适合于赋值器方法,但对于取值器的方法,你可能会希望他们返回你要的数据而不是返回this。不过,如果你把链式调用作为首要目标,希望所有方法的使用方式保持一致的话,那么变通的方法还是有的:你可以利用回调技术来返回所要的数据下面有两个例子:其中API类使用了普通的取值器(它中断了调用链),而API2类则使用了回调方法:

// Accessor without function callbacks: returning requested data in accessors.
window.API = window.API || {};
API.prototype = function() {
 var name = 'Hello world';
 // Privileged mutator method.
 setName: function(newName) {
 name = newName;
 return this;
 },
 // Privileged accessor method.
 getName: function() {
 return name;
 }
}();
// Implementation code.
var o = new API;
console.log(o.getName()); // Displays 'Hello world'.
console.log(o.setName('Meow').getName()); // Displays 'Meow'.
// Accessor with function callbacks.
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;
 }
}();
// Implementation code.
var o2 = new API2;
o2.getName(console.log).setName('Meow').getName(console.log);
// Displays 'Hello world' and then 'Meow'.

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数据结构与算法技巧总结》、《JavaScript常用函数技巧汇总》、《JavaScript操作DOM技巧总结》、《JavaScript页面元素操作技巧总结》及《JavaScript错误与调试技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

下载本文
显示全文
专题