( 285 => 347)JQ的继承方法

JQ的继承方法

使用方法:
// jQuery.extend 将一个方法扩展到函数下面,叫扩展静态方法
// jQuery.fn.extend 将一个方法扩展到原型对象下面,扩展实例方法
jQuery.extend = jQuery.fn.extend

// 当只写一个对象自变量的时候,JQ中扩展插件的形式
$.extend({
  aaa: function(){
    alert(1);
  },
  bbb: function(){
    alert(2);
  }
});

$.aaa();
$.bbb();

// 扩展JQ实例方法
$.fn.extend({
  aaa: function(){
    alert(3);
  },
  bbb: function(){
    alert(4);
  }
});

$().aaa();
$().bbb();

// 这里的this相当于$
$.extend(); -> this -> $ -> this.aaa -> $.aaa()
// 这里的this相当于$.fn
$.fn.extend(); -> this -> $.fn -> this.aaa -> $().aaa()

// 当写多个对象自变量的时候,后面的对象都是扩展到第一个对象身上
var a = {};
$.extend(a, { name: 'hello'}, {age: 30});
console.log(a);
{
  age: 30,
  name: 'hello'
}

// 还可以做 深拷贝 和 浅拷贝
// 浅拷贝,两个指针指向同一个对象
var a = {};
var b = { name: 'hello' };

$.extend(a, b);
a.name = 'hi';
alert(b.name);  // 可以正常修改


var a = {};
var b = { name: { age: 30 } };

$.extend(a, b);
a.name.age = 20;
alert(b.name.age);  // 可以正常修改 20

// 如何让里面的age不受影响呢
var a = {};
var b = { name: { age: 30 } };
// 添加true为深拷贝,就是两个不同的对象
$.extend(true, a, b);
a.name.age = 20;
console.log(a);  // { name: { age: 20 } }
console.log(b);  // { name: { age: 30 } }

jQuery源码解析

// 只有一个对象自变量
// JQ扩展插件
$.extend({
  aaa: function(){
    alert(1);
  }
});
// 扩展JQ实例方法
$.fn.extend({
  aaa: function(){
    alert(3);
  }
});

// 多个对象自变量,后面的对象都是扩展到第一个对象身上
var a = {};
$.extend(a, { name: 'hello'}, {age: 30}, {sex: 'man'});
  // 浅拷贝和深拷贝都是两个对象
  // 浅拷贝:拷贝第一层
  var a = {};
  var b = { name: 'hello', age: 30 };

  var a = {};
  var b = { name: { age: 30 } };
  $.extend(a, b);

  // 深拷贝:两个是不同的对象
  var a = {};
  var b = { name: { age: 30 } };
  $.extend(true, a, b);

/**
 * 首先要分清楚要扩展到谁身上,如果没有扩展对象,就创建一个 {}
 * 在确定好扩展对象之后
 * 再确定是深拷贝还是浅拷贝(或是只有一个对象)
 *  浅拷贝:
 *        横向遍历{{}, {}, {}}    深度遍历只需遍历一层{{name:{age:{oo: 'rr'}}, kk: 'll'}, {sex: 'hh'}}, name = 原来的对象{age:{oo: 'rr'}}, 不需要再往下递归遍历
 *  深拷贝:
 *        {{}, {}, {}} 横向遍历每一个对象和属性,{{name:{age:30}}, {sex: 'hh'}}, 递归遍历属性是对象的情况,每次都创建新的对象
 * 
 */

// jQuery.extend 将一个方法扩展到函数下面,叫扩展静态方法
// jQuery.fn.extend 将一个方法扩展到原型对象下面,扩展实例方法
jQuery.extend = jQuery.fn.extend = function() {
  var options, name, src, copy, copyIsArray, clone,
    // 目标元素(扩展到谁身上)
    // 多个对象自变量:扩展到 arguments[0] 身上
    target = arguments[0] || {}, 
    i = 1, // 开始遍历的下标
    length = arguments.length,
    // 默认不是深拷贝
    deep = false;

  // $.extend(true, a, b); 深拷贝的情况
  if ( typeof target === "boolean" ) {
    deep = target;
    // arguments[1]是否为 null undefined "" " 0
    target = arguments[1] || {};
    i = 2; 
  }

  // 因为要扩展到target身上,所以必须是对象或函数
  if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
    target = {};
  }

  // 看是不是插件的情况
  // $.extend({
  //   aaa: function(){
  //     alert(1);
  //   },
  //   bbb: function(){
  //     alert(2);
  //   }
  // });

  // $.aaa();
  // $.bbb();
  if ( length === i ) {
    // this 是 $ 或者 jQuery.fn = jQuery.prototype
    target = this;
    --i;
  }


  for ( ; i < length; i++ ) {
    // $.extend(a, { name: 'hello'}, {age: 30});
    // 从第二个参数开始,可以写n多个对象
    // 看一下argument后面的那些对象是否为空,并将arguments[i]赋值给options
    if ( (options = arguments[ i ]) != null ) {
      // name 是 键
      for ( name in options ) {
        // src是存在目标中的值
        src = target[ name ];
        // copy是options中所对应的值
        copy = options[ name ];

        // 防止循环引用
        // $.extend( a, { name: a });
        if ( target === copy ) {
          continue;
        }

        // 深拷贝
        // 如果是深拷贝 
        // var a = {};
        // var b = { name: { age: 30 } };
        // $.extend(true, a, b);
        // 比如说b就是一个对象
        // 也可以写成数组的形式 var c = [];
        if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
          /*
          var a = { name : {job: 'it' }};
          var b = { name: { age: 30 }}
          $.extend(true, a, b);
          console.log(a);
          {
            name: {
              job: 'it',
              age: 30
            }
          }
          */
          // 如果它是数组的情况
          if ( copyIsArray ) {
            copyIsArray = false;
            // clone是要扩展到的对象,对应这种情况{{name:{age:{oo: 'rr'}, kk: 'll'}}, {sex: 'hh'}}
            // 中的name,包含两个属性,所以得扩展到name身上,不能扩展到别地儿
            clone = src && jQuery.isArray(src) ? src : [];
          } else {
            clone = src && jQuery.isPlainObject(src) ? src : {};
          }

          // Never move original objects, clone them
          target[ name ] = jQuery.extend( deep, clone, copy );

        // 浅拷贝
        } else if ( copy !== undefined ) {
          // 扩展到target身上
          target[ name ] = copy;
        }
      }
    }
  }

  // Return the modified object
  return target;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值