jQuery 工具函式 (Utilities)
jQuery 提供了一系列實用的工具函式,這些函式不需要 DOM 元素,可以直接在 $ 或 jQuery 物件上呼叫,用於處理陣列、物件、類型判斷等常見任務。
陣列操作
$.each() - 迭代
遍歷陣列或物件的每個元素:
// 遍歷陣列
var fruits = ['蘋果', '香蕉', '橘子'];
$.each(fruits, function (index, value) {
console.log(index + ': ' + value);
});
// 0: 蘋果
// 1: 香蕉
// 2: 橘子
// 遍歷物件
var person = { name: 'John', age: 30, city: 'Taipei' };
$.each(person, function (key, value) {
console.log(key + ': ' + value);
});
// name: John
// age: 30
// city: Taipei
// 提前終止迭代(返回 false)
$.each(fruits, function (index, value) {
if (value === '香蕉') {
return false; // 停止迭代
}
console.log(value);
});
$.each() 是工具函式,而 .each() 是 jQuery 物件的方法。兩者功能類似但用途不同。$.map() - 映射轉換
將陣列或物件的每個元素經過函式處理後,返回新陣列:
// 陣列映射
var numbers = [1, 2, 3, 4, 5];
var doubled = $.map(numbers, function (value, index) {
return value * 2;
});
// [2, 4, 6, 8, 10]
// 可以返回 null 或 undefined 來排除元素
var filtered = $.map(numbers, function (value) {
return value > 2 ? value : null;
});
// [3, 4, 5]
// 可以返回陣列來展開元素
var expanded = $.map(numbers, function (value) {
return [value, value * 10];
});
// [1, 10, 2, 20, 3, 30, 4, 40, 5, 50]
// 物件映射
var person = { a: 1, b: 2, c: 3 };
var values = $.map(person, function (value, key) {
return value * 2;
});
// [2, 4, 6]
$.grep() - 過濾陣列
根據條件過濾陣列元素:
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 取得大於 5 的數字
var large = $.grep(numbers, function (value) {
return value > 5;
});
// [6, 7, 8, 9, 10]
// 第三個參數為 true 時,反轉過濾條件
var small = $.grep(
numbers,
function (value) {
return value > 5;
},
true
);
// [1, 2, 3, 4, 5]
// 過濾物件陣列
var users = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 },
{ name: 'Bob', age: 20 },
];
var adults = $.grep(users, function (user) {
return user.age >= 25;
});
// [{ name: 'John', age: 25 }, { name: 'Jane', age: 30 }]
$.merge() - 合併陣列
將兩個陣列合併為一個:
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var merged = $.merge(arr1, arr2);
// [1, 2, 3, 4, 5, 6]
// 注意:第一個陣列會被修改
console.log(arr1); // [1, 2, 3, 4, 5, 6]
// 如果不想修改原陣列,先複製一份
var merged = $.merge([], arr1);
$.merge(merged, arr2);
$.inArray() - 搜尋索引
在陣列中搜尋指定值,返回索引(找不到返回 -1):
var fruits = ['蘋果', '香蕉', '橘子'];
$.inArray('香蕉', fruits); // 1
$.inArray('葡萄', fruits); // -1
// 從指定索引開始搜尋
$.inArray('香蕉', fruits, 2); // -1(從索引 2 開始找不到)
// 用於判斷元素是否存在
if ($.inArray('香蕉', fruits) !== -1) {
console.log('有香蕉');
}
$.makeArray() - 轉為陣列
將類陣列物件轉為真正的陣列:
// NodeList 轉為陣列
var divs = document.querySelectorAll('div');
var divsArray = $.makeArray(divs);
// jQuery 物件轉為陣列
var $items = $('.item');
var itemsArray = $.makeArray($items);
// arguments 轉為陣列
function example() {
var args = $.makeArray(arguments);
console.log(args);
}
$.unique() / $.uniqueSort() - 去除重複
去除 DOM 元素陣列中的重複元素(僅適用於 DOM 元素):
// 取得所有連結的父元素(可能重複)
var parents = $('a')
.map(function () {
return this.parentNode;
})
.get();
// 去除重複
var uniqueParents = $.uniqueSort(parents);
$.unique() 在 jQuery 3.0 已改名為 $.uniqueSort()。此方法僅適用於 DOM 元素陣列,不適用於字串或數字陣列。物件操作
$.extend() - 合併物件
將一個或多個物件合併到目標物件:
// 基本合併
var defaults = { color: 'red', size: 10 };
var options = { size: 20, weight: 'bold' };
var result = $.extend({}, defaults, options);
// { color: 'red', size: 20, weight: 'bold' }
// 直接修改第一個物件
$.extend(defaults, options);
// defaults 變成 { color: 'red', size: 20, weight: 'bold' }
// 深層複製(第一個參數為 true)
var obj1 = { a: { b: 1 } };
var obj2 = { a: { c: 2 } };
// 淺層合併
$.extend({}, obj1, obj2);
// { a: { c: 2 } } - obj1.a 被覆蓋
// 深層合併
$.extend(true, {}, obj1, obj2);
// { a: { b: 1, c: 2 } } - 遞迴合併
$.extend() 常見用途
// 插件選項預設值
function myPlugin(options) {
var defaults = {
color: 'blue',
size: 'medium',
animate: true,
};
var settings = $.extend({}, defaults, options);
// 使用 settings...
}
myPlugin({ color: 'red' });
// settings = { color: 'red', size: 'medium', animate: true }
$.param() - 物件轉查詢字串
將物件轉為 URL 查詢字串格式:
var params = { name: 'John', age: 30 };
$.param(params);
// "name=John&age=30"
// 處理陣列
var params = { colors: ['red', 'blue'] };
$.param(params);
// "colors%5B%5D=red&colors%5B%5D=blue"
// 使用傳統模式(不加 [])
$.param(params, true);
// "colors=red&colors=blue"
// 巢狀物件
var params = {
user: {
name: 'John',
email: 'john@example.com',
},
};
$.param(params);
// "user%5Bname%5D=John&user%5Bemail%5D=john%40example.com"
類型判斷
$.type() - 精確類型判斷
返回值的精確類型:
$.type(true); // "boolean"
$.type(123); // "number"
$.type('hello'); // "string"
$.type(function () {}); // "function"
$.type([]); // "array"
$.type({}); // "object"
$.type(null); // "null"
$.type(undefined); // "undefined"
$.type(new Date()); // "date"
$.type(/regex/); // "regexp"
$.type(Symbol()); // "symbol"
$.isArray() - 是否為陣列
$.isArray([1, 2, 3]); // true
$.isArray('hello'); // false
$.isArray({ length: 3 }); // false
$.isFunction() - 是否為函式
$.isFunction(function () {}); // true
$.isFunction('hello'); // false
$.isNumeric() - 是否為數值
判斷是否為有限的數值(含數字字串):
$.isNumeric(123); // true
$.isNumeric('123'); // true
$.isNumeric('123.45'); // true
$.isNumeric(''); // false
$.isNumeric('hello'); // false
$.isNumeric(NaN); // false
$.isNumeric(Infinity); // false
$.isPlainObject() - 是否為純物件
判斷是否為使用 {} 或 new Object() 建立的物件:
$.isPlainObject({}); // true
$.isPlainObject({ a: 1 }); // true
$.isPlainObject(new Object()); // true
$.isPlainObject([]); // false
$.isPlainObject(new Date()); // false
$.isPlainObject(document.body); // false
$.isEmptyObject() - 是否為空物件
$.isEmptyObject({}); // true
$.isEmptyObject({ a: 1 }); // false
$.isEmptyObject([]); // true(陣列視為空物件)
$.isWindow() - 是否為 window 物件
$.isWindow(window); // true
$.isWindow({}); // false
字串處理
$.trim() - 去除首尾空白
$.trim(' hello world '); // "hello world"
$.trim('\n\t hello \n'); // "hello"
在現代 JavaScript 中,建議直接使用原生的
String.prototype.trim() 方法。HTML/JSON 解析
$.parseHTML() - 解析 HTML
將 HTML 字串解析為 DOM 元素陣列:
var html = '<div>Hello</div><span>World</span>';
var nodes = $.parseHTML(html);
// [div, span](DOM 元素陣列)
// 加入到頁面
$('#container').append(nodes);
// 第二個參數指定文件上下文
var nodes = $.parseHTML(html, document);
// 第三個參數允許包含 script 標籤(預設為 false)
var html = '<div>Hello</div><script>alert("hi")</script>';
var nodes = $.parseHTML(html, document, true); // 會包含 script
$.parseJSON() - 解析 JSON
var json = '{"name":"John","age":30}';
var obj = $.parseJSON(json);
// { name: "John", age: 30 }
$.parseJSON() 在 jQuery 3.0 已被棄用,請直接使用原生的 JSON.parse()。其他工具
$.noop - 空函式
一個什麼都不做的空函式,用於預設回呼:
// $.noop 等同於 function() {}
function doSomething(callback) {
callback = callback || $.noop;
// ...
callback();
}
$.now() - 當前時間戳
var timestamp = $.now(); // 等同於 Date.now()
建議直接使用原生的
Date.now()。$.contains() - 檢查 DOM 包含關係
判斷一個 DOM 元素是否包含另一個:
var container = document.getElementById('container');
var child = document.getElementById('child');
$.contains(container, child); // true(如果 child 在 container 內)
$.contains(child, container); // false
$.proxy() - 綁定 this
設定函式執行時的 this 值:
var obj = {
name: 'John',
greet: function () {
console.log('Hello, ' + this.name);
},
};
// 直接呼叫
obj.greet(); // "Hello, John"
// 當作回呼時,this 會改變
$('#btn').on('click', obj.greet); // "Hello, undefined"
// 使用 $.proxy 綁定 this
$('#btn').on('click', $.proxy(obj.greet, obj)); // "Hello, John"
// 或指定方法名稱
$('#btn').on('click', $.proxy(obj, 'greet')); // "Hello, John"
在現代 JavaScript 中,建議使用原生的
Function.prototype.bind() 或箭頭函式。$.globalEval() - 全域執行腳本
在全域範圍執行 JavaScript 程式碼:
$.globalEval('var globalVar = "hello";');
console.log(window.globalVar); // "hello"
實用範例
物件深拷貝
function deepClone(obj) {
return $.extend(true, {}, obj);
}
var original = { a: { b: 1 } };
var clone = deepClone(original);
clone.a.b = 2;
console.log(original.a.b); // 1(原物件未被修改)
移除陣列中的空值
function removeEmpty(arr) {
return $.grep(arr, function (value) {
return value != null && value !== '';
});
}
var arr = [1, '', null, 2, undefined, 3];
removeEmpty(arr); // [1, 2, 3]
物件轉為表單資料
function objectToFormData(obj) {
var formData = new FormData();
$.each(obj, function (key, value) {
if (Array.isArray(value)) {
$.each(value, function (i, v) {
formData.append(key + '[]', v);
});
} else {
formData.append(key, value);
}
});
return formData;
}
節流函式
function throttle(fn, delay) {
var lastCall = 0;
return function () {
var now = $.now();
if (now - lastCall >= delay) {
lastCall = now;
return fn.apply(this, arguments);
}
};
}
// 使用
$(window).on(
'scroll',
throttle(function () {
console.log('捲動');
}, 100)
);