jQuery工具函数

jQuery提供了一系列实用的工具函数,这些函数直接通过jQuery对象($)调用,可以帮助我们更高效地处理数据、操作对象和执行其他常见任务。

1. 数组操作

jQuery提供了一系列强大的数组操作工具函数,可以简化数组的遍历、筛选、转换等操作。

原始数组:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
操作结果:
点击按钮查看操作结果...

1.1 $.each() - 遍历数组或对象

$.each() 用于遍历数组或对象,功能类似于原生JavaScript的forEach。


// 遍历数组
const numbers = [1, 2, 3, 4, 5];
let sum = 0;

$.each(numbers, function(index, value) {
    sum += value;
    console.log(`索引 ${index}: 值 ${value}`);
});

console.log("总和:", sum); // 输出: 15

// 遍历对象
const person = {
    name: "张三",
    age: 25,
    city: "北京"
};

$.each(person, function(key, value) {
    console.log(`${key}: ${value}`);
});
// 输出:
// name: 张三
// age: 25
// city: 北京

// 在回调中中断遍历(返回false)
$.each(numbers, function(index, value) {
    if(value > 3) {
        return false; // 停止遍历
    }
    console.log(value); // 只输出: 1, 2, 3
});

// 遍历jQuery对象
$("li").each(function(index) {
    console.log(index + ": " + $(this).text());
});
                            

1.2 $.map() - 数组映射

$.map() 将数组或对象中的每个元素映射到新数组。


// 基本映射
const numbers = [1, 2, 3, 4, 5];
const doubled = $.map(numbers, function(value, index) {
    return value * 2;
});
console.log(doubled); // [2, 4, 6, 8, 10]

// 过滤无效值(返回null或undefined会被过滤)
const mixed = [1, 2, null, 4, undefined, 6];
const cleaned = $.map(mixed, function(value) {
    return value; // null和undefined会被过滤
});
console.log(cleaned); // [1, 2, 4, 6]

// 对象映射
const users = [
    {id: 1, name: "张三"},
    {id: 2, name: "李四"},
    {id: 3, name: "王五"}
];

const names = $.map(users, function(user) {
    return user.name;
});
console.log(names); // ["张三", "李四", "王五"]

// 复杂映射
const prices = [10, 20, 30];
const taxed = $.map(prices, function(price) {
    return {
        original: price,
        tax: price * 0.1,
        total: price * 1.1
    };
});
console.log(taxed);
                            

1.3 $.grep() - 数组过滤

$.grep() 根据条件过滤数组元素,返回新数组。


// 基本过滤
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 过滤偶数
const evenNumbers = $.grep(numbers, function(value, index) {
    return value % 2 === 0;
});
console.log(evenNumbers); // [2, 4, 6, 8, 10]

// 过滤奇数
const oddNumbers = $.grep(numbers, function(value) {
    return value % 2 !== 0;
}, false); // false表示保留满足条件的元素
console.log(oddNumbers); // [1, 3, 5, 7, 9]

// 反转过滤(第三个参数为true)
const notEven = $.grep(numbers, function(value) {
    return value % 2 === 0;
}, true); // true表示反转过滤条件
console.log(notEven); // [1, 3, 5, 7, 9]

// 复杂条件过滤
const products = [
    {id: 1, name: "鼠标", price: 50, stock: 10},
    {id: 2, name: "键盘", price: 150, stock: 5},
    {id: 3, name: "显示器", price: 800, stock: 0},
    {id: 4, name: "主机", price: 3000, stock: 2}
];

// 过滤有库存且价格低于1000的商品
const affordable = $.grep(products, function(product) {
    return product.stock > 0 && product.price < 1000;
});
console.log(affordable);
                            

1.4 其他数组工具函数


// $.inArray() - 查找元素在数组中的位置
const fruits = ["苹果", "香蕉", "橙子", "葡萄"];
const index = $.inArray("橙子", fruits);
console.log(index); // 2 (返回索引位置,从0开始)

const notFound = $.inArray("西瓜", fruits);
console.log(notFound); // -1 (未找到返回-1)

// $.makeArray() - 将类数组对象转换为真正的数组
const divs = document.getElementsByTagName("div");
console.log(divs instanceof Array); // false

const divArray = $.makeArray(divs);
console.log(divArray instanceof Array); // true

// $.merge() - 合并两个数组
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = $.merge(arr1, arr2);
console.log(merged); // [1, 2, 3, 4, 5, 6]
console.log(arr1); // [1, 2, 3, 4, 5, 6] (注意:第一个数组被修改)

// $.unique() - 从数组中移除重复元素(已弃用,使用$.uniqueSort())
const dupArray = [1, 2, 2, 3, 4, 4, 5];
const uniqueArray = $.unique(dupArray);
console.log(uniqueArray); // [1, 2, 3, 4, 5]
                            

2. 对象操作

jQuery提供了一些非常有用的对象操作工具函数,如对象扩展、深度复制等。

对象A:

                                    
对象B:

                                    
操作:

2.1 $.extend() - 对象扩展

$.extend() 用于将一个或多个对象合并到目标对象。


// 基本用法 - 合并对象
const defaults = {
    color: "red",
    size: "medium",
    price: 100
};

const options = {
    color: "blue",
    price: 150
};

const settings = $.extend({}, defaults, options);
console.log(settings);
// 输出: {color: "blue", size: "medium", price: 150}
// 注意:options中的属性覆盖了defaults中的同名属性

// 深度合并(递归合并)
const obj1 = {
    name: "John",
    address: {
        city: "New York",
        zip: "10001"
    }
};

const obj2 = {
    age: 30,
    address: {
        country: "USA",
        zip: "10002"
    }
};

const deepMerge = $.extend(true, {}, obj1, obj2);
console.log(deepMerge);
// 输出: {
//   name: "John",
//   age: 30,
//   address: {
//     city: "New York",
//     zip: "10002",
//     country: "USA"
//   }
// }

// 修改第一个参数(目标对象会被修改)
const target = {a: 1};
const source = {b: 2};
$.extend(target, source);
console.log(target); // {a: 1, b: 2}
console.log(source); // {b: 2}

// 合并多个对象
const objA = {a: 1};
const objB = {b: 2};
const objC = {c: 3};
const merged = $.extend({}, objA, objB, objC);
console.log(merged); // {a: 1, b: 2, c: 3}
                            

2.2 其他对象工具函数


// $.isEmptyObject() - 检查对象是否为空
console.log($.isEmptyObject({})); // true
console.log($.isEmptyObject({a: 1})); // false
console.log($.isEmptyObject([])); // true (数组被视为对象)
console.log($.isEmptyObject(null)); // true

// $.isPlainObject() - 检查是否为纯对象(通过{}或new Object创建)
console.log($.isPlainObject({})); // true
console.log($.isPlainObject(new Object())); // true
console.log($.isPlainObject([])); // false
console.log($.isPlainObject(null)); // false
console.log($.isPlainObject(window)); // false
console.log($.isPlainObject(new Date())); // false

// $.parseJSON() - 解析JSON字符串(已弃用,建议使用JSON.parse())
const jsonString = '{"name":"John","age":30}';
const obj = $.parseJSON(jsonString);
console.log(obj.name); // John

// 兼容性处理
const data = '{"name": "John"}';
let parsed;
try {
    parsed = JSON.parse(data);
} catch (e) {
    parsed = $.parseJSON(data); // 旧版本浏览器备用
}

// 深度克隆对象
function deepClone(obj) {
    return $.extend(true, {}, obj);
}

const original = {
    name: "Original",
    nested: {
        value: 1
    }
};

const cloned = deepClone(original);
cloned.nested.value = 2;

console.log(original.nested.value); // 1 (未受影响)
console.log(cloned.nested.value);   // 2
                            
提示: 在现代JavaScript开发中,许多jQuery对象操作函数已经被ES6+的语法替代,如扩展运算符、Object.assign()等,但了解这些函数对于维护旧代码仍然很重要。

3. 函数操作

jQuery提供了一些函数操作工具,如函数代理、延迟执行等。

3.1 $.proxy() - 函数代理

$.proxy() 用于改变函数执行时的上下文(this指向)。


// 基本用法
const person = {
    name: "张三",
    sayHello: function(greeting) {
        console.log(greeting + ", " + this.name);
    }
};

person.sayHello("Hello"); // Hello, 张三

// 改变this指向
const otherPerson = {name: "李四"};
const proxiedSayHello = $.proxy(person.sayHello, otherPerson);
proxiedSayHello("Hi"); // Hi, 李四

// 带参数的代理
const sayHelloTo = $.proxy(person.sayHello, person, "你好");
sayHelloTo(); // 你好, 张三

// 事件处理中的this问题(经典应用场景)
const buttonHandler = {
    message: "按钮被点击了",
    handleClick: function(event) {
        console.log(this.message);
        console.log("事件目标:", event.target);
    }
};

// 错误用法:this指向错误
$("#myButton").click(buttonHandler.handleClick); // this指向DOM元素

// 正确用法:使用$.proxy固定this指向
$("#myButton").click($.proxy(buttonHandler.handleClick, buttonHandler));

// 替代方案:使用箭头函数(ES6+)
$("#myButton").click((event) => {
    buttonHandler.handleClick(event);
});

// 多个参数的情况
const calculator = {
    multiply: function(a, b) {
        return a * b;
    }
};

const multiplyByTwo = $.proxy(calculator.multiply, calculator, 2);
console.log(multiplyByTwo(5)); // 10 (2 * 5)
                            

3.2 $.noop() - 空函数

$.noop() 返回一个空函数,什么都不做。


// 用作默认回调函数
function doSomething(callback) {
    // 如果没有提供回调函数,使用空函数
    callback = callback || $.noop;

    // 执行一些操作
    console.log("开始执行...");

    // 调用回调函数(可能是空函数)
    callback();
}

doSomething(); // 正常运行,不会报错
doSomething(function() {
    console.log("自定义回调");
});

// 插件开发中的默认选项
$.fn.myPlugin = function(options) {
    const settings = $.extend({}, {
        onStart: $.noop,
        onComplete: $.noop,
        onError: $.noop
    }, options);

    // 使用回调函数
    settings.onStart();

    // 插件逻辑...

    settings.onComplete();
};

// 使用插件
$("#element").myPlugin({
    onStart: function() {
        console.log("插件开始执行");
    }
});
                            

3.3 $.when() - 多异步操作管理

$.when() 用于管理多个异步操作,等待所有操作完成。


// 基本用法
const promise1 = $.ajax({url: "/api/data1"});
const promise2 = $.ajax({url: "/api/data2"});
const promise3 = $.ajax({url: "/api/data3"});

$.when(promise1, promise2, promise3)
    .done(function(data1, data2, data3) {
        console.log("所有请求完成");
        console.log("数据1:", data1);
        console.log("数据2:", data2);
        console.log("数据3:", data3);
    })
    .fail(function() {
        console.log("至少有一个请求失败");
    });

// 单个Deferred对象
$.when($.ajax("/api/data"))
    .done(function(data) {
        console.log("请求成功:", data);
    })
    .fail(function() {
        console.log("请求失败");
    });

// 非Deferred参数
$.when("hello", 123, true)
    .done(function(arg1, arg2, arg3) {
        console.log(arg1); // "hello"
        console.log(arg2); // 123
        console.log(arg3); // true
    });

// 模拟多个异步操作
function asyncTask1() {
    const dfd = $.Deferred();
    setTimeout(() => dfd.resolve("任务1完成"), 1000);
    return dfd.promise();
}

function asyncTask2() {
    const dfd = $.Deferred();
    setTimeout(() => dfd.resolve("任务2完成"), 2000);
    return dfd.promise();
}

$.when(asyncTask1(), asyncTask2())
    .done(function(result1, result2) {
        console.log("所有任务完成:");
        console.log(result1); // "任务1完成"
        console.log(result2); // "任务2完成"
    });
                            

4. 类型检测

jQuery提供了一系列类型检测函数,用于判断变量类型。

检测结果将显示在这里...

4.1 类型检测函数


// $.type() - 获取变量类型
console.log($.type(null));          // "null"
console.log($.type(undefined));     // "undefined"
console.log($.type(true));          // "boolean"
console.log($.type(123));           // "number"
console.log($.type("hello"));       // "string"
console.log($.type([]));            // "array"
console.log($.type({}));            // "object"
console.log($.type(new Date()));    // "date"
console.log($.type(function(){}));  // "function"
console.log($.type(/regex/));       // "regexp"

// 与typeof和instanceof的比较
const arr = [];
console.log(typeof arr);           // "object" (不准确)
console.log(arr instanceof Array); // true (但需要知道具体类型)
console.log($.type(arr));          // "array" (准确)

// $.isArray() - 检查是否为数组
console.log($.isArray([]));          // true
console.log($.isArray({}));          // false
console.log($.isArray("array"));     // false

// $.isFunction() - 检查是否为函数
console.log($.isFunction(function(){})); // true
console.log($.isFunction({}));           // false
console.log($.isFunction(alert));        // true

// $.isNumeric() - 检查是否为数字
console.log($.isNumeric(123));        // true
console.log($.isNumeric("123"));      // true (字符串数字)
console.log($.isNumeric("123abc"));   // false
console.log($.isNumeric(""));         // false
console.log($.isNumeric(null));       // false
console.log($.isNumeric(Infinity));   // false
console.log($.isNumeric(undefined));  // false
console.log($.isNumeric(NaN));        // false

// $.isWindow() - 检查是否为window对象
console.log($.isWindow(window));      // true
console.log($.isWindow(document));    // false

// 综合示例
function validateInput(value) {
    if($.isNumeric(value)) {
        console.log("输入的是数字:", parseFloat(value));
    } else if($.isArray(value)) {
        console.log("输入的是数组,长度:", value.length);
    } else if($.type(value) === "string") {
        console.log("输入的是字符串:", value);
    } else {
        console.log("未知类型:", $.type(value));
    }
}

validateInput(123);           // 输入的是数字: 123
validateInput([1, 2, 3]);     // 输入的是数组,长度: 3
validateInput("hello");       // 输入的是字符串: hello
validateInput({});            // 未知类型: object
                            

4.2 实际应用场景


// 参数类型检查
function calculateTotal(price, quantity) {
    // 验证参数类型
    if(!$.isNumeric(price) || !$.isNumeric(quantity)) {
        throw new Error("价格和数量必须是数字");
    }

    if(quantity < 0) {
        throw new Error("数量不能为负数");
    }

    return price * quantity;
}

// 安全地处理用户输入
function processUserInput(input) {
    // 尝试解析JSON
    if($.type(input) === "string") {
        try {
            input = JSON.parse(input);
        } catch(e) {
            // 不是有效的JSON,保持原样
        }
    }

    // 根据类型处理
    if($.isArray(input)) {
        return input.map(item => processUserInput(item));
    } else if($.isPlainObject(input)) {
        const result = {};
        $.each(input, function(key, value) {
            result[key] = processUserInput(value);
        });
        return result;
    } else if($.isNumeric(input)) {
        return parseFloat(input);
    } else {
        return input;
    }
}

// 示例调用
const userData = '{"name":"John","age":"30","scores":[90,"85",95]}';
const processed = processUserInput(userData);
console.log(processed);
// 输出: {name: "John", age: 30, scores: [90, 85, 95]}
                            

5. 字符串操作

jQuery提供了一些字符串操作工具函数,虽然功能相对简单,但在某些场景下很有用。

5.1 $.trim() - 去除空格

$.trim() 用于去除字符串两端的空格。


// 基本用法
const str1 = "   Hello World!   ";
console.log($.trim(str1)); // "Hello World!"

// 仅去除两端空格,中间空格保留
const str2 = "  Hello   World!  ";
console.log($.trim(str2)); // "Hello   World!"

// 处理制表符、换行符等空白字符
const str3 = "\t\n Hello World! \n\t";
console.log($.trim(str3)); // "Hello World!"

// 实际应用:表单验证
$("#submitBtn").click(function() {
    const username = $.trim($("#username").val());
    const password = $.trim($("#password").val());

    if(username === "" || password === "") {
        alert("用户名和密码不能为空");
        return;
    }

    // 提交表单
});

// 处理用户输入
function normalizeInput(input) {
    return $.trim(input).toLowerCase();
}

const userInput = "  JavaScript  ";
console.log(normalizeInput(userInput)); // "javascript"

// 数组中的字符串处理
const names = ["  Alice  ", "Bob  ", "  Charlie"];
const trimmedNames = $.map(names, function(name) {
    return $.trim(name);
});
console.log(trimmedNames); // ["Alice", "Bob", "Charlie"]
                            

5.2 字符串工具函数实际应用


// URL参数处理
function getQueryParams(url) {
    const params = {};
    const queryString = url.split("?")[1];

    if(queryString) {
        const pairs = queryString.split("&");

        $.each(pairs, function(index, pair) {
            const [key, value] = pair.split("=");
            if(key) {
                params[decodeURIComponent(key)] =
                    value ? decodeURIComponent(value) : "";
            }
        });
    }

    return params;
}

const url = "https://example.com/?name=张三&age=25&city=";
const params = getQueryParams(url);
console.log(params); // {name: "张三", age: "25", city: ""}

// 模板字符串处理(jQuery风格)
function formatString(template, data) {
    return template.replace(/\{(\w+)\}/g, function(match, key) {
        return data[key] !== undefined ? data[key] : match;
    });
}

const template = "欢迎{name},您的年龄是{age},来自{city}";
const user = {name: "张三", age: 25, city: "北京"};
console.log(formatString(template, user));
// 输出: "欢迎张三,您的年龄是25,来自北京"

// 字符串填充
function padLeft(str, length, char = " ") {
    str = String(str);
    while(str.length < length) {
        str = char + str;
    }
    return str;
}

function padRight(str, length, char = " ") {
    str = String(str);
    while(str.length < length) {
        str = str + char;
    }
    return str;
}

console.log(padLeft("5", 3, "0"));  // "005"
console.log(padRight("5", 3, "0")); // "500"

// 使用jQuery工具函数结合字符串操作
function processCSV(csvString) {
    // 去除空格和换行
    csvString = $.trim(csvString);

    const lines = csvString.split("\n");
    const result = [];

    $.each(lines, function(index, line) {
        // 跳过空行
        if($.trim(line) === "") return;

        const cells = line.split(",");
        const processedCells = $.map(cells, function(cell) {
            return $.trim(cell);
        });

        result.push(processedCells);
    });

    return result;
}

const csvData = `
  Name, Age, City
  张三, 25, 北京
  李四, 30, 上海

  王五, 28, 广州
`;

console.log(processCSV(csvData));
// 输出: [["Name", "Age", "City"], ["张三", "25", "北京"], ["李四", "30", "上海"], ["王五", "28", "广州"]]
                            
注意: 现代JavaScript (ES6+) 提供了很多原生的字符串操作方法,如String.prototype.trim()String.prototype.padStart()String.prototype.padEnd()等,建议优先使用原生方法。

jQuery工具函数速查表

函数 描述 示例
$.each() 遍历数组或对象 $.each(arr, fn)
$.map() 映射数组到新数组 $.map(arr, fn)
$.grep() 过滤数组元素 $.grep(arr, fn)
$.extend() 合并对象 $.extend(target, obj1, obj2)
$.proxy() 函数代理 $.proxy(fn, context)
$.type() 获取变量类型 $.type(obj)
$.isArray() 检查是否为数组 $.isArray(arr)
$.isFunction() 检查是否为函数 $.isFunction(fn)
$.isNumeric() 检查是否为数字 $.isNumeric(val)
$.trim() 去除字符串两端空格 $.trim(str)
$.noop() 空函数 callback = callback || $.noop
$.when() 管理多个异步操作 $.when(promise1, promise2)

实战练习:数据处理工具

使用jQuery工具函数创建一个数据处理工具:

处理结果:
处理结果将显示在这里...