window.onload 和 DOMcontentLoaded 的区别

下方代码的打印顺序是?

JS 自测题_块级作用域

答案

JS 自测题_javascript_02

解析

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),会弹出几?

JS 自测题_i++_03

答案:10

  • 解析:在 for 循环外定义 i,则 i 在 for 循环内是自由变量,点击事件触发时,访问的都是 for 循环外的 i 变量,此时 for 循环早已结束,i 值为 10

自由变量

当前作用域没有定义的变量 即自由变量

自由变量的查找,是 在函数定义的地方,向上级作用域查找
不是在执行的地方!

自测题1:下方代码会打印多少?

函数作为返回值

JS 自测题_i++_04


答案 100

自测题2:下方代码会打印多少?

JS 自测题_javascript_05


答案 100

自测题3:下方代码运行效果?

JS 自测题_i++_06


答案

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))