JQuery Data方法的一个小特技

开发 开发工具
通常我们在用 JavaScript 操作 DOM 元素的时候会往 DOM 上临时添加一些参数,用来记住一些状态,或者从后端取参数值等。

通常我们在用 JavaScript 操作 DOM 元素的时候会往 DOM 上临时添加一些参数,用来记住一些状态,或者从后端取参数值等。

[[190918]]

一般通过在 HTML 标签上添加自定义属性来实现,但是这样会不可避免的访问 DOM,性能上并不好。如果你使用 jQuery 的话建议使用 $el.data() 方法来取元素上 data-* 的值,比如:

  1. <div id="demo" data-key="value"></div> 
  2. <script> 
  3.     $('#demo').attr('data-key') 
  4.     $('#demo').data('key')  // ***次访问 DOM,以后从缓存取 
  5. </script> 

这两个方法的区别在于 attr 每次都会直接访问 DOM 元素,而 data 方法会缓存***次的查找,后续调用不需要访问 DOM。

很明显建议使用后者,但是在 低版本的 jQuery 中默认会对 data 方法取到的值进行粗暴的强制数据类型转换「parseFloat」。看下面代码:

  1. <div id="demo0" data-key="abc">字符串</div> 
  2. <div id="demo1" data-key="123">数字</div> 
  3. <div id="demo2" data-key="123e456">科学计数法</div> 
  4. <div id="demo3" data-key="0000123">八进制数字</div> 
  5. <script src="jquery-1.6.4"></script> 
  6. <script> 
  7.     $('#demo0').data('key')  // "abc" 
  8.     $('#demo1').data('key')  // 123 
  9.     $('#demo2').data('key')  // Infinity 
  10.     $('#demo3').data('key')  // 83 
  11. </script> 

后面两种显然出错了,就是因为 jQuery 对属性值进行了强制 parseFloat 操作。这种转换是方便了使用者,如果是数字的话我们取到这个值进行计算什么的就不用再转数据类型了,但是一不小心就会出 bug

发现这个 bug 的时候***感觉是 jQuery 不应该没考虑到这一点呀。后来果断去查了下***版的 jQuery 源代码,发现已经修复了。核心代码在 data.js 35 行,如下

  1. function getData( data ) { 
  2.     if ( data === "true" ) { 
  3.         return true; 
  4.     } 
  5.  
  6.     if ( data === "false" ) { 
  7.         return false; 
  8.     } 
  9.  
  10.     if ( data === "null" ) { 
  11.         return null; 
  12.     } 
  13.  
  14.     // Only convert to a number if it doesn't change the string 
  15.     // 重点就在这里 →_→ 
  16.     if ( data === +data + "" ) { 
  17.         return +data; 
  18.     } 
  19.  
  20.     if ( rbrace.test( data ) ) { 
  21.         return JSON.parse( data ); 
  22.     } 
  23.  
  24.     return data; 

getData 方法就返回了节点属性的值,只不过加了一些特殊处理使得我们取到了没有 bug 的值,关键地方就在这里: data === +data + "" 。这行代码做了些什么神奇的事情

将节点的属性值强制转换成数字「+data」后再转成字符串「+ ““」,如果转换后的值与原来相等就取转换后的值

可以简单的这么理解:jQuery 会尝试转换数据类型,如果转换后和转换前的 长得一样 那么 jQuery 就认为它是需要被转换成数字的。这样就可以***规避上面例子中的两种问题,我们来测试一下:

  1. var data = 'abc' 
  2. console.log(data === +data + "")        // false 不转换,直接返回字符串原值 
  3.  
  4. var data = '123' 
  5. console.log(data === +data + "")        // true 转换,使用转换后的数字类型值 
  6.  
  7. var data = '123e456' 
  8. console.log(data === +data + "")        // false 不转换,直接返回字符串原值 
  9.  
  10. var data = '0000123' 
  11. console.log(data === +data + "")        // false 不转换,直接返回字符串原值 

【本文是51CTO专栏作者周琪力的原创稿件,转载请注明出处】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2021-08-11 18:23:08

数据平台IT

2011-05-27 17:51:00

Android

2009-07-06 18:28:26

Java Socket

2017-04-26 14:48:01

Chrome程序扩展

2011-10-19 09:30:23

jQuery

2009-06-11 10:59:19

netbeans提示

2021-04-19 11:16:17

小程序微信开发

2009-09-01 16:03:32

C#单元测试

2012-12-07 10:04:58

管理项目管理日常管理

2012-11-19 11:07:42

IBMdw

2011-05-25 15:34:17

jQueryJSON

2020-08-12 22:03:17

JavaScript开发技术

2020-06-01 12:47:12

戴尔

2023-09-19 23:21:48

Python列表

2013-12-02 15:43:05

jQuery插件

2016-11-23 18:13:44

javascriptrxjsreactivex

2011-11-18 16:09:37

jQuery

2016-09-27 17:29:23

腾讯云小程序微信

2012-08-07 11:28:13

卸载linux

2019-04-04 09:11:41

微服务CDPLinkflow
点赞
收藏

51CTO技术栈公众号