window.onload 和 DOMcontentLoaded 的区别
下方代码的打印顺序是?
答案
解析
window.addEventListener("load", function () {
// 页面的全部资源加载完才会执行,包括图片视频等
});
document.addEventListener("DOMContentLoaded", function () {
// DOM 渲染完即可执行,此时图片、视频可能还没有加载完
});
创建 10 个
<a>
标签,点击的时候弹出来对应的序号
let a
for (let i = 0; i < 10; i++) {
a = document.createElement('a')
a.innerHTML = i + '<br>'
a.addEventListener('click', function (e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
- 原理:for 循环中定义 i 是块级作用域,10次循环形成10个块级作用域,点击时获取的 i 值即其序号。
若按以下写法(在 for 循环外定义 i),会弹出几?
答案:10
- 解析:在 for 循环外定义 i,则 i 在 for 循环内是自由变量,点击事件触发时,访问的都是 for 循环外的 i 变量,此时 for 循环早已结束,i 值为 10
自由变量
当前作用域没有定义的变量 即自由变量
自由变量的查找,是 在函数定义的地方,向上级作用域查找
不是在执行的地方!
自测题1:下方代码会打印多少?
函数作为返回值
答案 100
自测题2:下方代码会打印多少?
答案 100
自测题3:下方代码运行效果?
答案
100
10
10
setTimeout 测试
自测题1:下方代码会打印多少?
console.log(1);
setTimeout(function () {
console.log(2);
}, 1000);
console.log(3);
setTimeout(function () {
console.log(4);
}, 0);
console.log(5);
答案:
1
3
5
4
2
自测题2:下方代码会打印多少?
let i;
for (i = 1; i <= 3; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
答案
4
4
4
手写 Promise 加载一张图片
function loadImg(src) {
return new Promise(
(resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`图片加载失败 ${src}`)
reject(err)
}
img.src = src
}
)
}
使用范例
const url1 = '图片1的地址'
const url2 = '图片2的地址'
loadImg(url1).then(img1 => {
console.log(img1.width)
return loadImg(url2)
}).then(img2 => {
console.log(img2.width)
}).catch(err => console.error(err))