关于JQuery中$.data绑定数据原理或逻辑
问题:
JQuery中,对于.data([key],[value])函数,当使用其进行数据绑定时,假设要绑定的数据是“引用数据类型”,也就是对象;那么.data函数绑定的是该对象的副本还是该对象的一个引用?下面通过以下小例子来测试下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Test</title> 6 <style type="text/css"> 7 div{ 8 min-height: 40px; 9 width: 70%; 10 text-align: center; 11 padding: 10px; 12 border: 1px solid green; 13 } 14 </style> 15 <script src="jquery-1.11.1.js" type="text/javascript"></script> 16 </head> 17 <body> 18 <h3>测试$.data函数</h3> 19 <h4> 20 <li>当绑定的数据是有多层嵌套的JSON对象时,</li> 21 <li>给第一层DIV绑定第一层的JSON对象</li> 22 <li>给第二层DIV绑定第二层的JSON对象</li> 23 <li>......</li> 24 <li>那么,如果修改了第N层DIV绑定的JSON对象,则上层、上上层、。。。绑定的JSON对象会不会更新对应修改层的JSON对象?</li> 25 <li>---------</li> 26 <li>测试一:取数据 - 改取出的数据,不重新绑定 - 打印该元素的绑定数据</li> 27 <li>测试二:取数据 - 改取出的数据,重新绑定给该元素 - 打印该元素的绑定数据</li> 28 <li>测试三:取数据 - 改取出的数据,重新绑定给该元素 - 更新上级、上上级、...元素绑定的数据 - 打印该元素的绑定数据 和 上级、上上级、...元素绑定的数据</li> 29 <li>---------</li> 30 <li>测试一:已更新, 并且包括上级、上上级、...元素绑定的数据都更新了</li> 31 <li>测试二:OK</li> 32 <li>测试三:OK</li> 33 </h4> 34 <div class="first"> 35 <div class="second"> 36 <div class="third"></div> 37 </div> 38 </div> 39 <script type="text/javascript"> 40 var data = { 41 name: "first", 42 next: { 43 name: "second", 44 next: { 45 name: "third", 46 next: false 47 } 48 } 49 }; 50 $('.first').data('test', data); 51 $('.second').data('test', data["next"]); 52 $('.third').data('test', data["next"]["next"]); 53 54 //测试一 55 var td = $('.third').data('test'); 56 td["name"] = td["name"] + "-modify"; 57 58 //打印 59 console.log($('.first').data('test')); 60 console.log($('.second').data('test')); 61 console.log($('.third').data('test')); 62 </script> 63 </body> 64 </html>
使用Chrome打开该网页后,并查看页面的控制台打印如下:
由上图,可以推断出:$.data函数绑定给元素的对象时引用了该对象,而不是将对象“复制了一份”的副本绑定给元素;
也就是说,把一个对象绑定给A元素,再把该对象的子对象绑定给B元素,然后取出B元素绑定的对象,并修改这个取出的对象,之后,即使我们不把修改后的对象重新绑定给B元素;下次取B对象绑定的该数据时,他也已经被修改了;并且取A元素绑定的对象时,该对象中的绑定给B元素的子对象也显示被修改了;如以上代码:
我们在第55行、56行修改了.third的绑定的数据,之后第59行、60行、61行直接打印的当前对象、父对象、父父对象,显示都被修改了(也就是third变成了third-modify);
结论:
$.data函数绑定的对象是对源对象的一个引用,当我们修改该源对象时,绑定到元素上的对象也会“随之而修改(其实引用并未变,只是源对象发生了改变)”;
这下,只要我们绑定的数据是引用数据类型,大可放心、任意修改之了!