经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » jQuery » 查看文章
jQuery源码二之extend的实现
来源:cnblogs  作者:xy2370  时间:2019/9/10 10:54:16  对本文有异议

extend是jQuery中一个比较核心的代码,如果有查看jQuery的源码的话,就会发现jQuery在多处调用了extend方法。

作用

  1. 对任意对象进行扩展
  2. 扩展某个实例对象
  3. 对jquery本身的实例方法进行扩展

实现

基础版本, 对简单对象进行扩展
  1. jQuery.prototype.extend = jQuery.extend = function(){
  2. var target = arguments[0] || {}; //获取第一个参数作为目标结果
  3. var i = 1; //设置开始扩展的下标,扩展时第一个参数不会进行改变,不需要遍历
  4. var length = arguments.length;
  5. var option;
  6. if(typeof target !== 'object') {
  7. target = {};
  8. }
  9. for(; i< length; i++){
  10. option = arguments[i]
  11. for(var name in option){
  12. target[name] = option[name]
  13. }
  14. }
  15. return target
  16. }
  17. //调用
  18. var i = {a: 0};
  19. var b = {c: 9};
  20. console.log($().extend(i,b)) // {a:0, c:9}
升级版本1.0, 对复杂对象进行扩展。

在上面,我们已经写出的extend的基础版本,但是如果我们简单测试一下,就会发现仍是有问题存在的。
我们可以使用上面的方法,对下面的对象进行扩展

  1. var n = {
  2. al: 90,
  3. m: {
  4. d: 23,
  5. }
  6. }
  7. var b = {m:{
  8. c: 98
  9. }};
  10. console.log($().extend(n,b)) // {al: 90, m: { c: 98 }}

简单的从结果来看,返回的结果并不符合我们的预期,基础版本的方法似乎只是简单的值替换而已。那么来简单升级一下代码吧。
在升级代码之前,需要了解一下关于浅拷贝和深拷贝的相关。

关于浅拷贝和深拷贝的那些事
  1. 浅拷贝,
    对于浅拷贝,我的简单理解就是: 浅拷贝就是对最表面的层级进行拷贝,如果某一被拷贝对象的值发生了改变,最终的拷贝结果也会随之发生改变。
  1. var i = {a: 0};
  2. var b = {c: 9};
  3. console.log($().extend(i,b)) // {a: 90, c:9}
  4. i.a = 90
  1. 深拷贝,深拷贝主要的是面对复杂对象,如果浅拷贝是对最表面的一层进行拷贝,那么深拷贝就是,对拷贝对象的每一个层级都进行拷贝,某种层面来说,勉强算得上是递归的浅拷贝吧,但是比较不同的是,深拷贝中,如果某一个被拷贝对象的值发生了改变,拷贝结果是不会随之发生变化的,是一个独立的存储空间。
  1. var n = {
  2. al: 90,
  3. m: {
  4. d: 23,
  5. }
  6. }
  7. var b = {m:{
  8. c: 98
  9. }};
  10. console.log($().extend(true,{},n,b))
  11. console.log(n)
  12. n.al = "cs"

结果:
Image text

深拷贝extend代码扩展

jQuery.extend是提供深拷贝的,需要将第一参数传为true。
基本思路:

  1. 首先先对第一个传入参数进行判断,判断是否是boolean类型,来决定是否需要进行深拷贝;
  1. var deep = false;
  2. if (typeof target === 'boolean') {
  3. deep = target;
  4. target = arguments[1];
  5. i = 2; //因为第一参数为boolean,所以拷贝对象从argument[1]开始,但通常第一个拷贝对象是不需要比遍历的,所以遍历下标从2开始。
  6. }
  1. 对需要遍历的对象进行判断,判断是否是复杂类型。使用extend对jquery进行扩展。
  1. if (length === i) { //此时extend参数只有一个,但是目标应该是this,所以获取到this;
  2. target = this; //但同时 i = 1;无法进行遍历,所以将遍历下标后退一位
  3. i--;
  4. }
  5. jQuery.extend({
  6. isArray: function(obj) {
  7. return toString.call(obj) === '[object Array]';
  8. },
  9. isPainObj: function(obj) {
  10. return toString.call(obj) === '[object Object]';
  11. }
  12. })
  1. extend方法改造。
  1. jQuery.prototype.extend = jQuery.extend = function(){
  2. var target = arguments[0] || {};
  3. var i = 1;
  4. var length = arguments.length;
  5. var option, copy, src, copyisArray, clone;
  6. for(; i< length; i++){
  7. if((option = arguments[i]) != null ){
  8. for(name in option) {
  9. src = target[name];
  10. copy = option[name];
  11. if(jQuery.isPainObj(copy) || (copyisArray = jQuery.isArray(copy))) {
  12. if(copyisArray) {
  13. copyisArray = false;
  14. clone = src && jQuery.isArray(src) ? src : [];
  15. } else {
  16. clone = src && jQuery.isPainObj(src) ? src : {};
  17. }
  18. target[name] = jQuery.extend(clone,copy)
  19. } else if(copy !== undefined) {
  20. target[name] = copy
  21. }
  22. }
  23. }
  24. }
  25. return target
  26. }

行了,到这里为止,我们就已经完成了简单的extend函数了,其实比较重要的是深拷贝和浅拷贝,关于这一点,下次再记录吧。

原文链接:http://www.cnblogs.com/xya-b/p/11472611.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号