认识手术台:jQuery 包装对象与 ready


文档摘要

1.1 认识手术台:jQuery 包装对象与 ready 别以为 返回的就是页面上那个元素本体——这是初学者踩得最深的第一口井。上一章说过本章是开机检查,这一节就负责把开机后最关键的两个部件拆开给你看: 这个工厂函数到底造出了什么,以及 为什么规定"术前必须等患者躺好"。理解了这两点,后续六章的所有 API 才有安放的位置。 本节摘要: 是 全局函数的别名,它接收选择器、DOM 节点、HTML 片段或就绪回调,返回一个"伪数组 + 方法集"的 jQuery 对象;jQuery 对象与原生节点可以互转但不能混用方法。 回调保证 DOM 就绪后才执行操作,对应原生的 事件。

1.1 认识手术台:jQuery 包装对象与 ready

别以为 $('#bed') 返回的就是页面上那个元素本体——这是初学者踩得最深的第一口井。上一章说过本章是开机检查,这一节就负责把开机后最关键的两个部件拆开给你看:$ 这个工厂函数到底造出了什么,以及 ready 为什么规定"术前必须等患者躺好"。理解了这两点,后续六章的所有 API 才有安放的位置。

本节摘要$jQuery 全局函数的别名,它接收选择器、DOM 节点、HTML 片段或就绪回调,返回一个"伪数组 + 方法集"的 jQuery 对象;jQuery 对象与原生节点可以互转但不能混用方法。ready 回调保证 DOM 就绪后才执行操作,对应原生的 DOMContentLoaded 事件。

先看一次误诊:把手术衣当成了患者本人

假设页面里有一个挂号窗口:

<button id="take-num" class="btn">取号</button>

下面这段代码,运行时直接报错:

var btn = $('#take-num'); btn.innerHTML = '叫号中'; // 悄悄失败:jQuery 对象没有 innerHTML 属性 btn.disabled = true; // 悄悄失败:同样写不进去

诡异之处在于它不报错、也不生效——给一个对象赋不存在的属性,JavaScript 不会阻止你。正确写法要么脱掉手术衣直接操作节点,要么用 jQuery 自己的方法:

var btn = $('#take-num'); btn[0].innerHTML = '叫号中'; // 取出下标 0 处的原生节点 btn.text('叫号中'); // 或者用 jQuery 的 text 方法 btn.prop('disabled', true); // jQuery 的属性写法

这口井的成因,就是本节要拆解的核心:$() 返回的不是节点,而是包着节点的 jQuery 对象

工厂函数的四种入参形态

$ 是全局函数 jQuery 的别名,两者指向同一个函数:

console.log($ === jQuery); // true

它像挂号窗口的分流员,按你递来的东西决定干什么:

// 形态一:选择器字符串 → 在文档里查找,返回包装后的匹配集合 var items = $('.item'); // 形态二:原生 DOM 节点 → 把它包进 jQuery 对象(不查找,直接包) var body = $(document.body); // 形态三:HTML 片段 → 创建新节点并包装(还没进文档) var fresher = $('<li class="item">新患者</li>'); // 形态四:回调函数 → 等价于 ready,文档就绪后执行 $(function () { console.log('DOM 已就绪,可以动刀'); });

第四种形态是最常见的开机姿势:$(function () { ... })$(document).ready(function () { ... }) 完全等价,前者只是后者的语法糖。

手术衣之下:伪数组结构的解剖

jQuery 对象是一件"带工具袋的手术衣",衣襟上按顺序别着所有匹配到的原生节点——下标从零开始,有 length,却不是真正的数组。

图:jQuery 对象包装结构解剖

图:jQuery 对象包装结构解剖

在浏览器控制台里可以验证这个结构:

var items = $('.item'); console.log(items.length); // 4:匹配到四个元素 console.log(items[0]); // 第一个原生 li 节点 console.log(items instanceof Array); // false:不是真数组 console.log(items.jquery); // '3.7.1':jQuery 对象的自我标识

遍历这批元素有两条路,注意工具归属不同:

// 原生循环:items[i] 是裸节点,只能用原生 API for (var i = 0; i < items.length; i++) { items[i].style.color = 'red'; } // jQuery 的 each:包好的元素逐个交给你,这里直接用 jQuery 方法 items.each(function (index) { $(this).text('第 ' + index + ' 号已叫号'); });

each 回调里的 this裸节点,所以循环体内还要再 $() 包一次才能调用 jQuery 方法——这是新手第二口井,记住"脱衣取节点、穿衣用方法"就摔不进去。

与原生节点的互转

手术衣穿脱自如,两条路都要会走:

var jq = $('.item'); // jQuery 对象 var raw = jq[0]; // 脱衣:按下标取节点 var raw2 = jq.get(1); // 脱衣:get 方法取第 2 个(负数下标从尾数) var node = document.querySelector('.item'); var wrapped = $(node); // 穿衣:裸节点包成 jQuery 对象

原生对照:document.querySelectorAll('.item') 返回的是静态 NodeList,同样可用下标访问与 forEach 遍历,但它没有 addClasson 这类方法——差异全在"衣服上缝了什么"。另外 NodeList 是静态快照,文档变化不会反映进来;而 jQuery 集合也是查询瞬间的快照,这点两者一致,反倒是 live 时代"集合自动更新"的老行为早已废弃。

ready:术前必须等患者躺好

脚本如果放在 <head> 里执行,此刻 <body> 还没被解析,查什么都是空。ready 就是解决时机的机制:把你的手术排进队列,等 DOM 树构建完成再动刀。

$(document).ready(function () { console.log('queue 的子元素数量:', $('#queue .item').length); }); // 简写,效果相同 $(function () { $('#take-num').on('click', function () { console.log('叫号'); }); });

原生对照是 DOMContentLoaded

document.addEventListener('DOMContentLoaded', function () { console.log('原生:DOM 就绪'); });

两者的差别值得记牢。其一,jQuery 的 ready 可以注册多个回调且按注册顺序全部执行,原生写法同样支持多次 addEventListener,但老式的 window.onload = fn 只留最后一个。其二,window.onload 要等样式表、图片等资源全部下载完才触发,ready 只要 DOM 树搭好就触发——分诊台不需要等药房的货到齐才开门。其三,jQuery 3 起 ready 总是异步执行,即便文档早已就绪,回调也会排队到当前代码跑完之后,这与原生的行为对齐了。

动手验证

把下面这段放进页面底部的 <script>,打开控制台对照输出:

$(function () { console.log('1. $ === jQuery :', $ === jQuery); var items = $('#queue .item'); console.log('2. 匹配数量 :', items.length); console.log('3. 是数组吗 :', items instanceof Array); console.log('4. 裸节点标签 :', items[0].tagName); items.each(function (i) { console.log('5. 第', i, '个:', $(this).text()); }); });

预期输出依次是 true、队列条目数、falseLI,以及逐条文本。如果你的第二条输出是零,多半是脚本写在 <head> 里又没等 ready——恰好复习了本节后半段。

要点复盘

  • $jQuery 是同一个函数,四种入参分别对应查找、包装、创建、就绪回调。
  • jQuery 对象是伪数组:有 length 和下标,不是 Array 实例;方法缝在对象上,不在裸节点上。
  • 脱衣用 [0].get(i),穿衣用 $(node)each 回调里的 this 是裸节点。
  • ready 对应原生 DOMContentLoaded,比 window.onload 早;$(function(){}) 是它的简写。
  • 给 jQuery 对象赋 DOM 属性会静默失败——写不出效果时,先怀疑自己拿的是不是手术衣。

下一节把镜头从运行机制拉到工程决策:版本那么多,你的项目该上哪一台。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U