全部学科
Python全栈
python
NodeJS全栈
nodejs
📝 1 篇文章 20 道配套习题

JS高级语法与特性

专题说明

本专题系统讲解JavaScript高级语法特性,涵盖原型链机制、ES Modules模块化、事件循环原理、Proxy/Reflect元编程、生成器与迭代器协议、高阶函数与函数式编程、闭包高级应用等核心进阶知识。

学习目标

  1. 理解原型链的查找机制与__proto__、prototype的关系
  2. 掌握ES Modules的静态特性与导入导出机制
  3. 深入理解事件循环的微任务与宏任务执行顺序
  4. 掌握Proxy的拦截操作与Reflect API的使用
  5. 理解生成器的yield机制与迭代器协议
  6. 掌握高阶函数、柯里化、偏函数的实现原理
  7. 理解函数式编程的不可变性原则
  8. 掌握闭包的形成条件与经典应用场景

学习内容

本专题涵盖以下核心知识点:

  • 原型链:原型链查找机制、__proto__与prototype关系、原型链顶端、实例与原型修改的影响
  • 模块化(ES Modules):静态结构特性、import提升、export default与named export区别、动态导入
  • 事件循环(Event Loop):微任务与宏任务分类、执行顺序、setTimeout(0)实际延迟、await的微任务特性
  • 代理与反射(Proxy/Reflect):13种拦截操作、Reflect API作用、可撤销代理、与Object.defineProperty对比
  • 生成器与迭代器:yield机制、next参数传递、迭代器协议、可迭代协议、Symbol.iterator
  • 高阶函数与函数式编程:高阶函数定义、柯里化实现、偏函数应用、函数组合、不可变性原则
  • 闭包:闭包形成条件、独立闭包实例、循环中的闭包问题、IIFE与闭包的关系

学习建议

  1. 先理解原型链的基本结构,重点掌握__proto__与prototype的区别
  2. 深入理解事件循环机制,能够准确判断代码的执行顺序
  3. 掌握Proxy的13种拦截操作,理解Reflect与Proxy的配合使用
  4. 理解生成器的yield机制,掌握next参数传递的原理
  5. 掌握柯里化与偏函数的实现,理解函数式编程的核心思想
  6. 通过闭包经典问题(循环闭包、计数器)深入理解闭包特性

📝 配套习题(20 题)

💡 参考答案在文末
判断题
1

setTimeout(fn, 0) 会立即执行回调函数,因为它设置了0毫秒延迟。

A

B

2

requestAnimationFrame可以替代节流函数用于动画和视觉更新场景,因为它自动以浏览器刷新率(通常60fps)执行回调。

A

B

3

IIFE(立即执行函数表达式)本身不是闭包,但它常用于创建闭包的封闭作用域。

A

B

4

Proxy可以拦截整个对象的所有操作,而Object.defineProperty只能拦截单个属性的读写操作。

A

B

单选题
5

以下代码实现了偏函数,输出结果是什么?

JavaScript
const partial = (fn, ...presetArgs) =>
  (...laterArgs) => fn(...presetArgs, ...laterArgs);

const add = (a, b, c) => a + b + c;
const addFiveAndTwo = partial(add, 5, 2);

console.log(addFiveAndTwo(3));
console.log(addFiveAndTwo(10));
A

10 17

B

8 15

C

10 15

D

5 12

6

以下代码的输出结果是什么?

JavaScript
// module.js
let value = 1;
export default value;
export { value as v };

// main.js
import defaultExport, { v } from './module.js';
value = 2;
console.log(defaultExport, v);
A

1 2

B

2 2

C

1 1

D

ReferenceError

7

以下代码的输出结果是什么?

JavaScript
console.log('1');

setTimeout(() => console.log('2'), 0);

Promise.resolve()
  .then(() => console.log('3'))
  .then(() => console.log('4'));

console.log('5');

async function asyncFunc() {
  console.log('6');
  await Promise.resolve();
  console.log('7');
}
asyncFunc();

queueMicrotask(() => console.log('8'));
A

1 5 6 3 4 7 8 2

B

1 5 6 3 7 4 8 2

C

1 5 3 4 6 7 8 2

D

1 5 6 3 7 8 4 2

8

以下代码的输出结果是什么?

JavaScript
const obj = { a: 1 };
console.log(obj.__proto__ === Object.prototype);
console.log(Object.prototype.__proto__);
A

true null

B

true undefined

C

false null

D

true Object.prototype

9

以下哪个选项准确描述了高阶函数的定义?

A

返回值是数字类型的函数

B

接收函数作为参数或返回函数的函数

C

只能处理数组操作的函数

D

必须使用箭头函数语法定义的函数

10

关于 ES Modules 的特性,以下说法正确的是?

A

import语句可以放在代码的任意位置,与变量声明类似

B

ES Module的导入是静态分析,可以在运行时动态修改

C

被导入的模块会被提升到模块顶部,在代码执行前完成加载

D

import导入的变量可以在当前模块中重新赋值

11

以下代码的输出结果是什么?

JavaScript
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}

// 改为let后
for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log(j), 100);
}
A

3 3 3; 0 1 2

B

0 1 2; 0 1 2

C

3 3 3; 3 3 3

D

undefined; 0 1 2

12

以下代码实现了函数柯里化,输出结果是什么?

JavaScript
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    }
    return function(...moreArgs) {
      return curried.apply(this, args.concat(moreArgs));
    };
  };
}

const sum = (a, b, c) => a + b + c;
const curriedSum = curry(sum);

console.log(curriedSum(1)(2)(3));
console.log(curriedSum(1, 2)(3));
A

6 6

B

[1, 2, 3] [1, 2, 3]

C

6 undefined

D

TypeError

13

以下代码的输出结果是什么?

JavaScript
function* generator() {
  const a = yield 1;
  const b = yield a * 2;
  yield b * 3;
}

const gen = generator();
console.log(gen.next());
console.log(gen.next(10));
console.log(gen.next(20));
A

{value: 1} {value: 20} {value: 60}

B

{value: 1} {value: 20} {value: 40}

C

{value: undefined} {value: 20} {value: 60}

D

{value: 1} {value: 10} {value: 30}

14

以下代码的输出结果是什么?

JavaScript
function outer() {
  let count = 0;
  return function inner() {
    count++;
    return count;
  };
}

const counter1 = outer();
const counter2 = outer();

console.log(counter1());
console.log(counter1());
console.log(counter2());
A

1 2 1

B

1 1 1

C

1 2 3

D

0 1 0

15

以下哪种方式符合函数式编程的不可变性原则?

A

直接修改传入的对象参数

B

使用Object.assign或扩展运算符创建新对象返回

C

使用let声明变量并多次修改

D

使用数组的push方法添加元素

16

以下代码的输出结果是什么?

JavaScript
function Foo() {}
Foo.prototype.a = 1;

const foo = new Foo();
Foo.prototype = { b: 2 };

console.log(foo.a, foo.b);
A

1 undefined

B

undefined 2

C

1 2

D

undefined undefined

多选题
17

关于 Reflect API 的作用,以下说法正确的是?

A

Reflect提供与Proxy handler同名的方法,用于执行对象的默认行为

B

Reflect.get(obj, 'prop')与obj['prop']完全等价

C

Reflect方法通常返回布尔值表示操作是否成功,便于在Proxy handler中使用

D

Reflect.apply可以替代Function.prototype.apply.call

E

Reflect只能与Proxy配合使用,单独使用没有意义

18

以下哪些操作会被Proxy的handler拦截?

A

proxy.name(属性读取)

B

proxy.name = 'value'(属性设置)

C

Object.keys(proxy)

D

proxy instanceof SomeClass

E

delete proxy.name

19

以下哪些选项会产生微任务(Microtask)?

A

setTimeout(() => {}, 0)

B

Promise.resolve().then(() => {})

C

queueMicrotask(() => {})

D

MutationObserver.observe()

E

requestAnimationFrame(() => {})

填空题
20

实现迭代器协议需要定义一个____________方法,该方法返回一个包含________________________属性的对象。可迭代对象需要实现[Symbol.iterator]方法,返回一个迭代器对象。

参考答案
1.错误 2.正确 3.正确 4.正确 5.A 6.C 7.B 8.A 9.B 10.C 11.A 12.A 13.A 14.A 15.B 16.A 17.A;C;D 18.A;B;C;E 19.B;C;D 20.next;value;done
想在手机上练习这套专题?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码
← 上一个专题 JS高级性能分析
扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码