jQuery.extend 与 fn.extend 区别

jQuery.extend 和 jQuery.fn.extend 的用法和区别

问题

jQuery.extendjQuery.fn.extend 有什么区别?

解答

jQuery.extend

jQuery.extend 有两个用途:

1. 扩展 jQuery 本身(添加静态方法)

// 添加静态方法
jQuery.extend({
  min: function(a, b) {
    return a < b ? a : b;
  },
  max: function(a, b) {
    return a > b ? a : b;
  }
});

// 调用方式:直接通过 jQuery 调用
jQuery.min(2, 3); // 2
jQuery.max(4, 5); // 5
$.min(2, 3);      // 2

2. 合并对象

// 浅拷贝合并
var obj1 = { a: 1, b: 2 };
var obj2 = { b: 3, c: 4 };
var result = $.extend(obj1, obj2);
console.log(result); // { a: 1, b: 3, c: 4 }
console.log(obj1);   // { a: 1, b: 3, c: 4 } - obj1 被修改

// 深拷贝合并(第一个参数传 true)
var obj3 = { a: { x: 1 } };
var obj4 = { a: { y: 2 } };
var deep = $.extend(true, {}, obj3, obj4);
console.log(deep); // { a: { x: 1, y: 2 } }

jQuery.fn.extend

jQuery.fn.extend 用于扩展 jQuery 原型,添加实例方法(插件开发常用)。

// jQuery.fn 就是 jQuery.prototype
console.log(jQuery.fn === jQuery.prototype); // true

// 添加实例方法
jQuery.fn.extend({
  // 检查元素是否可见
  isVisible: function() {
    return this.css('display') !== 'none';
  },
  // 设置红色背景
  redBg: function() {
    return this.css('background-color', 'red');
  }
});

// 调用方式:通过 jQuery 对象实例调用
$('#myDiv').isVisible(); // true 或 false
$('.box').redBg();       // 所有 .box 元素背景变红

对比示例

// $.extend - 静态方法
$.extend({
  sayHello: function(name) {
    return 'Hello, ' + name;
  }
});
$.sayHello('World'); // "Hello, World"

// $.fn.extend - 实例方法
$.fn.extend({
  highlight: function(color) {
    return this.css('background-color', color || 'yellow');
  }
});
$('p').highlight();       // 所有 p 元素背景变黄
$('p').highlight('pink'); // 所有 p 元素背景变粉

源码角度理解

// 简化版实现原理
jQuery.extend = jQuery.fn.extend = function() {
  var target = arguments[0] || {};
  
  // 如果只传一个对象,则扩展到 this 上
  // this 是 jQuery 时,扩展静态方法
  // this 是 jQuery.fn 时,扩展实例方法
  if (arguments.length === 1) {
    target = this;
  }
  
  // 遍历并复制属性...
};

关键点

  • $.extend 扩展 jQuery 本身,添加静态方法,通过 $.method() 调用
  • $.fn.extend 扩展 jQuery 原型,添加实例方法,通过 $('selector').method() 调用
  • $.fn 就是 jQuery.prototype 的别名
  • $.extend 还可用于对象合并,第一个参数传 true 实现深拷贝
  • 开发 jQuery 插件时,通常使用 $.fn.extend