程序员鸡皮-前端程序员|PHP程序员|全栈程序员 - JavaScript
type: channel
link: https://www.xvzhu.cn/tag/JavaScript/
items: 异步编程方案四-《await/async》
items: CSS3引入的主要新特性是什么？
items: 在Javascript的script标签中，async属性和refer属性的区别是什么？
items: async属性是什么？它有什么作用？
items: defer属性在JavaScript标签中有什么作用？
items: Javascript高级（二）深入浏览器的渲染原理
items: JavaScript相关this指向面试题
items: Javascript高级（一） 函数中的this指向
items: 重学Javascript基础（十三) 阶段性项目华为商城
items: 重学Javascript基础（十二) BOM相关对象学习

异步编程方案四-《await/async》
type: item
date: 2026-04-26T21:14:00+08:00
description: 其实我们现在已经不是必须使用Generator来实现异步代码编写成同步代码的结构了function fetchData(url){ return new Promist((resolve)=>{ setTimeout(()=>{ resolve(`${url} data~`) },2000); }) } // 定义函数：异步函数 async function getData(){ const res1 = await fetchData("aaa") console.log(res1) const res2 = await fetchData(res1 + "bbb") console.log(res2) const res3 = await fetchData(res2+"ccc") console.log(res3) } getData()感谢观看

CSS3引入的主要新特性是什么？
type: item
date: 2026-03-10T22:12:57+08:00
description: 其实并不存在正真意义上的CSS3定义，因为CSS3并不是一个单一的规范，而是一系列独立模块的组合，这些模块扩展了CSS3的功能。这种模块模块化的方法允许不同的特性以不同的速度发展，可以更快的标准化一些特性，而不必等待整个规范的形成。这里我们可以看下面这几个模块：选择器 Selectors在css3中的新的特性比如[attr^=value]属性值以特定的字符串开始，当然还新增了结构性伪类，比如:nth-child、:nth-last-child、:first-of-type背景和边框 Backgrounds and Borders新增了边框图片可以使用图片来定义盒子的边框border-image。多重背景可以支持在单个元素上使用多个背景图片。文本效果 Text Effets文本阴影，可以将文本后面添加阴影的效果text-shadow。还有文本溢出属性text-overflow可以控制文本溢出容器之后的显示方式。转换和动画2D和3D之间的转换：我们可以使用transform,包括螺旋rotate，缩放scale，倾斜skew，平移translate。CSS动画animation运行定义关键帧动画，控制动画序列。感谢大家观看

在Javascript的script标签中，async属性和refer属性的区别是什么？
type: item
date: 2026-03-08T23:06:00+08:00
description: 标签的defer属性和async属性用来控制外部文件的加载和执行方式。它对于改善网页的加载速度有很大帮助。但是他们的机制不同，defer属性不会阻塞DOM树的渲染，并且defer属性的执行是在DOM树渲染之后DOMContentLoaded事件之前执行，还有就是多个defer属性执行是按照代码顺序执行的。async属性在执行的时候也不会阻塞DOM树的构建，但是它不会保证是不是在DOMContentLoaded之前或者之后执行，并且多个async属性的标签不按照顺序依次执行，因为它是独立的哪一个先加载完哪一个先运行。运行场景由于以上特性造成了他们的使用场景不同，defer属性通常是用在DOM树构建完成操作DOM的场景，并且对script脚本的运行顺序有限制的。然而async属性通常使用在对网站检控或者广告类型的这些对DOM树构建不需要依赖的，独立运行的js脚本。现代化框架开发解决方案在现代化框架开发过程中，往往不需要我们自己来配置async或者defer:在使用脚手架或者自己搭建的webapck或者vite项目进行打包时，它会根据需要帮我们加上defer属性。某些情况下我们想要进行性能优化时，也可以手动的加上async属性,例如一些第三方的分析工具或者广告追踪脚本。感谢大家观看

async属性是什么？它有什么作用？
type: item
date: 2026-03-08T22:40:00+08:00
description: async属性和defer属性目标一样它也是为了不让js阻塞DOM树的构建。不过他们两个还是有区别的。async让js脚本的下载和执行是独立的。浏览器不会因为async属性的script脚本的执行而阻塞，这一点和defer属性类似。然而async属性比较任性，只要脚本被浏览器下载完成之后就会立即执行，不会等待在DOMContentLoaded之前执行。所以它不能保证是在DOMContentLoaded事件之前或者之后执行。并且它在执行的时候会阻塞DOM树的构建。代码如下图所示：下面我们看一下，async属性和defer属性的区别，下方的图片很详细。[那我们这个async属性有什么用呢？感觉有defer属性就够了，其实当我们引用那些统计网站数据的第三方脚本的时候就可以使用async属性。它的执行不会影响当前站点的DOM树渲染，就比如百度收录的验证代码或者bing的还有统计网站的其他代码或广告代码。感谢大家观看

defer属性在JavaScript标签中有什么作用？
type: item
date: 2026-03-08T22:17:00+08:00
description: 我们知道，当浏览器在执行到script标签的时候，首先会停止构建DOM树，然后下载Javascript文件并且执行，当JavaScript脚本执行完毕之后才会继续解析HTML标签构建DOM树。为什么Javascript程序会这样做呢？原因是我们的Javascript的作用就是操作DOM并且可以修改DOM。如果我们等到HTML执行完成之后再去执行JavaScript就会造成严重的回流和重绘，尤其是现代化编程中大部分用的都是Vue和React框架。页面都是由Javascript来渲染页面的，十分影响网页性能。所以在渲染DOM树的情况下，当遇到Javascript都会先下载然后执行，再渲染DOM树。为了解决这个问题，JavaScript语言的script标签给了我们两个属性：defer属性和async属性。defer的作用是什么？defer属性告诉我们，让页面不要等待JavaScript语言下载，而是继续执行HTML构建DOM树。脚本会由浏览器来执行下载，这个过程不会阻塞构建DOM树。如果脚本下载好了，他会等待DOM树构建好了，在DOMContentLoaded事件执行之前执行JavaScript程序defer中的代码。如下图：所以反过来说，DOMContentLoaded事件总会等待defer中的代码执行完毕之后再运行。还有值得一提的是当页面中有多个script标签中有defer属性的时候，它会根据标签的先后顺序依次进行。所以defer属性推荐放到script标签中，并且最好放在head标签中。为什么最好放在head标签中呢？因为DOM树构建的过程中，会按照标签的先后顺序执行，假如我们将带defer属性的script标签放到最后。其实不会有多大效果，从内存的角度来说就是带defer属性的script标签相当于给我们的代码新增了一个线程来执行代码。当然不影响DOM树的构建。这里我们考虑到了下载JavaScript代码也是需要时间的。不如放在head标签中增加效率。感谢大家观看

Javascript高级（二）深入浏览器的渲染原理
type: item
date: 2024-11-01T15:50:00+08:00
description: 网页的解析过程我们的浏览器在一个网页解析的过程中，如何执行呢？其实一个网页在执行中，先下载我们的html基本框架，当遇到link标签加载.css文件的时候会下载，下载了css会生成CSSOM树，这里的加载不是阻塞下载，然而当遇到.js文件的时候就去下载.js文件，下载js文件的时候是阻塞下载。然后，将CSSOM树挂载到html上，然后将下载出来的js文件再用于html上，再执行渲染，从而生成真实DOM。注意在这里渲染的时候会先做layout布局，判断文档样式解构，并且查看是否display:none,有就不显示了，并且绘制图像。这里我们就不得不讲讲浏览器内核了。浏览器内核常见的浏览器内核：1.Trident（三叉戟）：IE、360安全浏览器、搜狗高速浏览器、百度浏览器、UC浏览器；Gecko（壁虎）：Mozilla Firefox；2.Presto（急板乐曲）->Blink（眨眼）：Opera3.Webkit：Safari、360极速浏览器、搜狗高速浏览器、移动端浏览器（Android、iOS）4.Webkit->Blink：Google Chrome，Edge我们最常用的谷歌浏览器v8引擎是Blink内核的。我们经常说的浏览器内核指的是浏览器的排版引擎：排版引擎（layout engine），也称为浏览器引擎（browser engine）、页面渲染引擎（rendering engine）或样版引擎浏览器渲染流程渲染引擎如何解析页面我们先看下面这张图更详细的解析流程：https://www.html5rocks.com/en/tutorials/internals/howbrowserswork解析一：html的解析过程1.因为默认情况下服务器会给浏览器返回index.html文件，所以解析HTML是所有步骤的开始：2.解析HTML，会构建DOM Tree解析二：生成CSS规则在解析的过程中，如果遇到CSS的link元素，那么会由浏览器负责下载对应的CSS文件： 注意：下载CSS文件是不会影响DOM的解析的；浏览器下载完CSS文件后，就会对CSS文件进行解析，解析出对应的规则树：我们可以称之为CSSOM（CSS Object Model，CSS对象模型）；解析三–构建Render Tree当有了DOM Tree和CSSOM Tree后，就可以两个结合来构建Render Tree了注意一：link元素不会阻塞DOM Tree的构建过程，但是会阻塞Render Tree的构建过程这是因为Render Tree在构建时，需要对应的CSSOM Tree；注意二：Render Tree和DOM Tree并不是一一对应的关系，比如对于display为none的元素，压根不会出现在render tree中；解析四–布局（layout）和绘制（Paint）第四步是在渲染树（Render Tree）上运行布局（Layout）以计算每个节点的几何体。渲染树会表示显示哪些节点以及其他样式，但是不表示每个节点的尺寸、位置等信息；布局是确定呈现树中所有节点的宽度、高度和位置信息；第五步是将每个节点绘制（Paint）到屏幕上在绘制阶段，浏览器将布局阶段计算的每个frame转为屏幕上实际的像素点；包括将元素的可见部分进行绘制，比如文本、颜色、边框、阴影、替换元素（比如img）回流和重绘解析理解回流reflow：（也可以称之为重排）第一次确定节点的大小和位置，称之为布局（layout）。之后对节点的大小、位置修改重新计算称之为回流。什么情况下引起回流呢？比如DOM结构发生改变（添加新的节点或者移除节点）；比如改变了布局（修改了width、height、padding、font-size等值）比如窗口resize（修改了窗口的尺寸等）比如调用getComputedStyle方法获取尺寸、位置信息；理解重绘repaint：第一次渲染内容称之为绘制（paint）。之后重新渲染称之为重绘。什么情况下会引起重绘呢？比如修改背景色、文字颜色、边框颜色、样式等；回流一定会引起重绘，所以回流是一件很消耗性能的事情。所以在开发中要尽量避免发生回流：修改样式时尽量一次性修改 比如通过cssText修改，比如通过添加class修改尽量避免频繁的操作DOM我们可以在一个DocumentFragment或者父元素中将要操作的DOM操作完成，再一次性的操作；尽量避免通过getComputedStyle获取尺寸、位置等信息；对某些元素使用position的absolute或者fixed并不是不会引起回流，而是开销相对较小，不会对其他元素造成影响。合成和性能优化特殊解析–composite合成绘制的过程，可以将布局后的元素绘制到多个合成图层中。这是浏览器的一种优化手段；默认情况下，标…

JavaScript相关this指向面试题
type: item
date: 2024-10-22T15:05:00+08:00
description: 这篇文章用来整理this指向相关面试题，我们请看内容面试题一var name = "window"; var person = { name: "person", sayName: function () { console.log(this.name); } }; function sayName() { var sss = person.sayName; sss(); // 绑定: 默认绑定, window -> window person.sayName(); // 绑定: 隐式绑定, person -> person (person.sayName)(); // 绑定: 隐式绑定, person -> person (b = person.sayName)(); // 术语: 间接函数引用, window -> window } sayName();上面代码执行之后依次打印window person person window解释一下，这里的第一个window是上面的person对象里面的sayName函数，那么我们这里调用的this为什么不是指向我们preson对象呢？原因是我们sayName方法使用环境，将sayName函数重新赋值给了一个变量sss,我们调用sss()执行sayName方法，当我们调用sss的时候我们当前的环境是在windows中，所以我们可以理解，假如我们直接调用person.sayName()才是打印person对象，也就是我们第二个打印出person的隐式绑定的方法。第二个person的由来：第二个person我们知道当小括号包裹一段内容这段内容可以看做一个整体，并且先运行，所以我们可以将第一个小括号里的内容先运行出来，没错他就是我们的sayName方法，众所周知，函数体在JavaScript中是堆内存，所以我们执行这里只是调用了这个内存地址，并不关person的事，然后我们将这个内存地址运行的时候就需要在后面加个新的小括号了，这里讲的就是函数的调用。最后一个window打印的时候，是将我们的person.sayName方法间接赋值给了一个全局变量b并且执行，假如在最后我们打印b变量会发现是ƒ () {console.log(this.name);}和我们打印sss的时候情况一模一样，所以就能体会到JavaScript实际使用中的玄妙了吧。面试题二var name = 'window' // {} -> 对象 // {} -> 代码块 var person1 = { name: 'person1', foo1: function () { console.log(this.name) }, foo2: () => console.log(this.name), foo3: function () { return function () { console.log(this.name) } }, foo4: function () { // console.log(this) // 第一个表达式this -> person1 // console.log(this) // 第二个表达式this -> person2 // console.log(this) // 第三个表达式this -> person1 return () => { console.log(this.name) } } } var person2 = { name: 'person2' } // 开始题目: person1.foo1(); // 隐式绑定: person1 person1.foo1.call(person2); // 显式绑定: person2 person1.foo2(); // 上层作用域: window person1.foo2.call(person2); // 上层作用域: window person1.foo3()(); // 默认绑定: window person1.foo3.call(person2)(); // 默认绑定: window person1.foo3().call(person2); // 显式绑定: person2 person1.foo4()(); // person1 person1.foo4.call(person2)(); // person2 person1.foo4().call(person2); // person1上面执行之后在控制台打印：person1 person2 window window window window person2 person1 person2 person1person1.foo1()这里打印person1,由于是由person…

Javascript高级（一） 函数中的this指向
type: item
date: 2024-10-20T12:06:00+08:00
description: this指向的定义this是JavaScript中定义的关键字，作用就是谁调用指向谁，没用明确定义的对象的时候，就会指向默认对象，默认绑定全局对象。还是对他的定义有不是很理解的地方，就让我们仔细看这篇文章吧。this定义特点函数在调用时，JavaScript默认给this绑定一个值this的绑定和定义的位置没有关系this的绑定和调用方式以及调用的位置有关this是在运行时被绑定的从特点来看，this是调用函数才有，不调用就没有明确定义，在调用的时候调用方式和调用位置起到了重要作用。this的绑定规则既然是调用的时候才有，那么this绑定肯定有好多的绑定规则，并不是随便就能将this绑定到某个对象上。this绑定规则又分为：默认绑定隐式绑定显式绑定new绑定下面就具体了解这四种绑定方式：默认绑定默认绑定是什么呢？当独立函数的调用的时候，可以理解成函数没有绑定到某个对象上进行调用。这就是我们的默认调用我们看几个(常见的默认绑定)例子：// 定义函数 function foo(name) { console.log("foo函数:", this) } // 1.方式一: 直接调用 foo()上面这个我们就是window对象了，为什么呢，因为我们foo()这个函数是在window调用的。我们再看另外一个： // 定义函数 function foo(name) { console.log("foo函数:", this) } // 2.方式二: 通过对象调起 var obj = { name: "why" } obj.aaa = foo obj.aaa()在这里我们就是obj这个对象了，因为我们是在obj这个对象调用的。隐式绑定也就是它的调用位置中，是通过某个对象发起的函数调用。让我们看几个例子： function foo() { console.log("foo函数:", this) } var obj = { bar: foo } obj.bar()这里的this就是foo对象了显式绑定如果我们不希望在对象内部包含这个函数的引用，同时又希望在这个对象上进行强制调用的时候，我们就需要使用显式绑定了。常用的显式绑定有call和apply,还有不常用的显式绑定bindcall那么我们的call显式绑定如何使用呢，请看下面：// 显式绑定 var obj = { name: "why" } function foo() { console.log("foo函数:", this) } // 执行函数, 并且强制this就是obj对象 foo.call(obj) foo.call(123) foo.call("abc")这里我们如果传入参数123,或者abc这种参数的话，this会自动生成一个数组或者字符串类，并且打印出来类型。applyapply如何使用呢，其实apply函数和call函数使用方式差不多，单也有点区别。// call/apply function foo(name, age, height) { console.log("foo函数被调用:", this) console.log("打印参数:", name, age, height) } // ()调用 // foo("why", 18, 1.88) // apply // 第一个参数: 绑定this // 第二个参数: 传入额外的实参, 以数组的形式 // foo.apply("apply", ["kobe", 30, 1.98]) // call // 第一个参数: 绑定this // 参数列表: 后续的参数以多参数的形式传递, 会作为实参 foo.call("call", "james", 25, 2.05)由上面代码我们可以总结出call函数传参是foo.call("call", "james", 25, 2.05)这样传递，然而apply参数传递是foo.apply("apply", ["kobe", 30, 1.98])，传入的数组，这就是这两个的区别，相同点就是call和apply都是显式绑定。bind在 bind() 被调用时，这个新函数的 this 被指定为 bind() 的第一个参数，而其余参数将作为新函数的参数，供调用时使用。下面我们看一个示例：function foo(name, age, height, address) { console.log("foo:", this) console.log("参数:", name, age, height, address) } var obj = { name: "why" } // 需求: 调用foo时, 总是绑定到obj对象身上(不希望obj对象身上有函数) // 1.bind函数的基本使用 // v…

重学Javascript基础（十三) 阶段性项目华为商城
type: item
date: 2024-10-17T00:11:00+08:00
description: 01.商品列表-界面搭建 Document 首页 > 笔记本 分类： 笔记本 台式机 智慧屏 服务优惠： 仅看有货 分期免息 优惠商品 排序： 综合 最新 评论数 价格 HUAWEI MateBook E 12.6英寸 1 预订立省300元|12期免息 ¥6499 分期免息 赠送积分 3190人评论 96% 好评 HUAWEI MateBook E 12.6英寸 2 预订立省300元|12期免息 ¥6499 分期免息 赠送积分 3190人评论 96% 好评 HUAWEI MateBook E 12.6英寸 2 预订立省300元|12期免息 ¥6499 分期免息 赠送积分 3190人评论 96% 好评 HUAWEI MateBook E 12.6英寸 2 预订立省300元|12期免息 ¥6499 分期免息 赠送积分 3190人评论 96% 好评 02.商品列表-动态列表 Document 首页 > 笔记本 分类: 笔记本 台式机 智慧屏 服务优惠: 仅看有货 分期免息 优惠商品 排序: 综合 最新 评论数 价格 <!-- HUAWEI MateBook E 12.6英寸 预订立省300元|12期免息 ¥6499 分期免息 赠送积分 3190人评论 96% 好评 --> 03.商品列表-动态列表(重构) Document 首页 > 笔记本 分类: 笔记本 台式机 智慧屏 服务优惠： 仅看有货 分期免息 优惠商品 排序： 综合 最新 评论数 价格 04.商品列表-服务优惠-点击 Document 首页 > 笔记本 分类： 笔记本 台式机 智慧屏 服务优惠： 仅看有货 分期免息 优惠商品 排序： 综合 最新 评论数 价格 05.商品列表-服务优惠-过滤 Document 首页 > 笔记本 分类： 笔记本 台式机 智慧屏 服务优惠： 仅看有货 分期免息 优惠商品 排序： 综合 最新 评论数 价格 06.轮播图-界面搭建 Document 上一个 下一个 07.轮播图-轮播控制 Document 上一个 下一个 08.轮播图-自动轮播 Document 上一个 下一个 09.轮播图-指示器展示 Document 上一个 下一个 10.轮播图-位移滚动 Document 上一个 下一个 11.轮播图-无限滚动 Document 上一个 下一个 12.商品列表-服务优惠-排序 Document 首页 > 笔记本 分类： 笔记本 台式机 智慧屏 服务优惠： 仅看有货 分期免息 优惠商品 排序： 综合 好评 评论数 价格 13.商品列表-服务优惠-排序(debug) Document 首页 > 笔记本 分类： 笔记本 台式机 智慧屏 服务优惠： 仅看有货 分期免息 优惠商品 排序： 综合 好评 评论数 价格 感谢大家观看，我们下次见

重学Javascript基础（十二) BOM相关对象学习
type: item
date: 2024-10-13T19:02:54+08:00
description: 01.BOM-window对象的使用 Document 百度一下 关闭窗口 02.BOM-location对象的使用 Document 打开新的网页 替换新的网页 网页重新加载 03.BOM-history对象的使用 Document 修改history 返回上一级 04.BOM-navigator对象的使用 Document 05.BOM-screen对象的使用 Document 06.JSON的文件格式-简单值12307.JSON的文件格式-数组[ "123", 123 ]08.JSON的文件格式-对象{ "name":"why", "age":123, "friend":{ "name":"kobe", "age":null } }09.JSON-JSON的序列化 Document 10.JSON-stringify方法的补充 Document 11.JSON-parse方法的补充 Document 感谢大家观看，我们下次见