• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >jquery > jQuery 3.0 的 setter和getter 模式详解

jQuery 3.0 的 setter和getter 模式详解

作者:snandy 字体:[增加 减小] 来源:互联网

snandy 通过本文主要向大家介绍了jquery3.0,getter和setter等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

jQuery 的 setter/getter 共用一个函数,通过是否传参来表明它是何种意义。简单说传参它是 setter,不传它是 getter。

一个函数具有多种意义在编程语言中并不罕见,比如函数重载:一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载的好处是减少了函数名的数量,避免了名字空间的污染,对于程序的可读性也大有裨益。

函数重载主要体现的两个方面,一是参数的类型、相同个数的参数类型不同可称为函数重载;二是参数的个数,个数不同也称为函数重载。注意,重载与函数的返回值并无关系。

由于 JS 弱类型的特征,想模拟函数重载就只能通过第二种方式:参数的个数来实现。因此函数内的 arguments 对象就显得非常重要。

以下是一个示例

function doAdd() {
var argsLength = arguments.length
if (argsLength === 0) {
return 0
} else if (argsLength === 1) {
return arguments[0] + 10
} else if (argsLength === 2) {
return arguments[0] + arguments[1]
}
}
doAdd() // 0
doAdd(5) // 15
doAdd(5, 20) // 25

doAdd 通过判断函数的参数个数重载实现了三种意义,argsLength 为 0 时,直接返回 0; argsLength 为 1 时,该参数与 10 相加;argsLength 为 2 时两个参数相加。

利用函数重载特性可以实现 setter/getter

function text() {
var elem = this.elem
var argsLength = arguments.length
if (argsLength === 0) {
return elem.innerText
} else if (argsLength === 1) {
elem.innerText = arguments[0]
}
} 

以上简单的解释了函数重载及利用它实现 setter/getter。即"取值器"与"赋值器"合一。到底是取值还是赋值,由函数的参数决定。jQuery 的很多 API 设计大量使用了这种模式。

下图汇总了 jQuery 中采用这种模式的所有 API,共 14 个函数

所有这些函数内部都依赖另一个函数 access, 毫不夸张的说 access 是所有这些函数的核心,是实现 setter/getter 的核心。下面是这个函数的源码,它是一个私有的函数,外部是调用不到它的。

access 的源码如下

// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
  var i = 0,
    len = elems.length,
    bulk = key == null;
  // Sets many values
  if ( jQuery.type( key ) === "object" ) {
    chainable = true;
    for ( i in key ) {
      access( elems, fn, i, key[ i ], true, emptyGet, raw );
    }
  // Sets one value
  } else if ( value !== undefined ) {
    chainable = true;
    if ( !jQuery.isFunction( value ) ) {
      raw = true;
    }
    if ( bulk ) {
      // Bulk operations run against the entire set
      if ( raw ) {
        fn.call( elems, value );
        fn = null;
      // ...except when executing function values
      } else {
        bulk = fn;
        fn = function( elem, key, value ) {
          return bulk.call( jQuery( elem ), value );
        };
      }
    }
    if ( fn ) {
      for ( ; i < len; i++ ) {
        fn(
          elems[ i ], key, raw ?
          value :
          value.call( elems[ i ], i, fn( elems[ i ], key ) )
        );
      }
    }
  }
  return chainable ?
    elems :
    // Gets
    bulk ?
      fn.call( elems ) :
      len ? fn( elems[ 0 ], key ) : emptyGet;
};

该函数的注释提到:这是一个多功能的函数,用来获取和设置一个集合元素的属性和值。value 可以是一个可执行的函数。这个函数一共不到 60 行代码。从上往下读,第一个 if 是设置多个 value 值,是一个递归调用。刨去这个递归调用,设置单个值的代码也就不到 50 行了。写的非常简练、耐读。

为了理解 access 函数,我画了两个图

access 内部两个主要分支

access 内部的执行流程

access 定义的形参有 7 个

1.elems 元素集合,实际调用时传的都是 this,这里的 this 是 jQuery 对象,我们知道 jQuery 对象本身是一个集合,具有 length 属性和索引。必传。

2.fn 实现 setter/getter 的函数,就是说这个函数里需要有条件能判断哪部分是 setter,哪部分是 getter。必传。

3.key 比如 attr 和 prop 方法要传,设置或获取哪个 key 的值。有的则不用传,但为了占位用以 null 替代,比如 text、html 方法。可选。

4.value 仅当 setter 时要传,即 value 为 undefined 时是 getter,否则是 setter。可选。

5.chainable 当为 true 时,进入 setter 模式,会返回 jQuery 对象。false 则进入 getter模式。调用时通过 arguments.length 或 arguments.length>1 传入。

6.emptyGet 当 jQuery 对象为空时,返回的结果,默认不传为 undefined,data 方法调用时传的是 null。

7.raw 当 value 为函数类型时 raw 为 false,否则为 true。

上面提到了 access 是 jQuery 所有 setter/getter 函数的核心,换句话说所有 14 个函数 setter/getter 函数内部都会调用 access。这也是为什么 access 有 7 个参数,里面分支众多。因为它要处理的各种条件就很多呢。但所有这些 setter/getter 有很多类同的代码,最后还是提取一个公共函数。

为了便于理解,我把 access 的调用分类以下,便于我们理解。

1. 调用 access 时,第三个参数 key 传值为 null,分别是 text/html 方法

text: function( value ) {
  return access( this, function( value ) {
    return value === undefined ?
      jQuery.text( this ) :
      this.empty().each( function() {
        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
          this.textContent = value;
        }
      } );
  }, null, value, arguments.length );
},
html: function( value ) {
  return access( this, function( value ) {
    var elem = this[ 0 ] || {},
      i = 0,
      l = this.length;
    if ( value === undefined && elem.nodeType === 1 ) {
      return elem.innerHTML;
    }
    // See if we can take a shortcut and just use innerHTML
    if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
      !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
      value = jQuery.htmlPrefilter( value );
      try {
        for ( ; i < l; i++ ) {
          elem = this[ i ] || {};
          // Remove element nodes and prevent memory leaks
          if ( elem.nodeType === 1 ) {
            jQuery.cleanData( getAll( elem, false ) );
            elem.innerHTML = value;
          }
        }
        elem = 0;
      // If using innerHTML throws an exception, use the fallback method
      } catch ( e ) {}
    }
    if ( elem ) {
      this.empty().append( value );
    }
  }, null, value, arguments.length );
},

图示这两个方法在 access 内部执行处

为什么 key 传 null,因为 DOM API 已经提供了。text 方法使用 el.innerText 设置或获取;html 方法使用 innerHTML 设置或获取(这里简单说,实际还有一些异常处理)。

2. 与第一种情况相反,调用 access 时 key 值传了且不为 null。除了 text/html 外的其它 setter 都是如此

attr: function( name, value ) {
  return access( this, jQuery.attr, name, value, arguments.length > 1 );
},
prop: function( name, value ) {
  return access( this, jQuery.prop, name, value, arguments.length > 1 );
},
// Create scrollLeft and scrollTop methods
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
  var top = "pageYOffset" === prop;
  jQuery.fn[ method ] = function( val ) {
    return access( this, function( elem, method, val ) {
      var win = getWindow( elem );
      if ( val === undefined ) {
        return win ? win[ prop ] : elem[ method ];
      }
      if ( win ) {
    



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入理解jQuery3.0的domManip函数
  • jQuery3.0中的buildFragment私有函数详解
  • jQuery 3.0十大新特性最终版发布
  • jQuery 3.0 的 setter和getter 模式详解
  • jQuery 3.0十大新特性
  • 浅析jQuery 3.0中的Data
  • jQuery 3.0 的变化及使用方法

相关文章

  • JQuery 操作/获取table具体代码
  • jQuery web 组件 后台日历价格、库存设置的代码
  • jQuery实现checkbox列表的全选、反选功能
  • jquery 分页控件实现代码
  • 浅谈jQuery中对象遍历.eq().first().last().slice()方法
  • jQuery检测返回值的数据类型
  • jquery插件treegrid树状表格的使用方法详解(.Net平台)
  • 基于jquery的分页控件(C#)
  • 用JQuery调用Session的实现代码
  • jQuery层级选择器_动力节点节点Java学院整理

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • jQuery中add实现同时选择两个id对象
    • 基于JQuery实现图片上传预览与删除操作
    • jquery实现可旋转可拖拽的文字效果代码
    • jquery实现简洁文件上传表单样式
    • jQuery Validate 无法验证 chosen-select元素的解决方法
    • 使用jQuery的ajax方法向服务器发出get和post请求的方法
    • JQuery简单实现锚点链接的平滑滚动
    • Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
    • jQuery中on()方法用法实例详解
    • 动态加载jquery库的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有