Skip to content

解构赋值(Day1 2/2) ​

本页对应 Day01_ES6,共 6 段视频,约 1 小时 26 分。

学习目标 ​

  • 能使用对象解构按属性名提取变量,完成重命名、属性名与变量名一致时的简写、默认值设置,并正确说明缺失属性得到 undefined。
  • 能对嵌套对象、数组、字符串及内置对象应用对象解构,提取所需属性或方法,并区分“属性名用于匹配”与“变量名用于接收值”。
  • 能在函数参数中使用对象解构,处理传入对象缺少属性、额外属性及不传参数等情形。
  • 能使用反引号定义模板字符串,直接书写换行与缩进,并通过 ${} 插入变量和表达式;能结合 map 与 join 生成 HTML 字符串。
  • 能正确调用常见 ES5 字符串方法完成字符获取、查找、截取、大小写转换、分割与替换,并说明其基本用途。
  • 能使用 ES6 新增字符串方法 repeat、includes、startsWith、endsWith、padStart、padEnd、trim、trimStart、trimEnd、replaceAll,说明其返回值类型及是否修改原字符串。

知识点 ​

一、先把目的想清楚:解构赋值是在“拆数据给变量” ​

本节笔记先记住两条:

text
1. 解构赋值是指按照一定模式,从数组和对象中提取值,对变量进行赋值,或函数传参
2. 等号的右边需要写数组或者对象(可以是任何形式,变量、直接量、表达式)
   等号的左边要求将变量写在数组或者或者对象结构中,并不是真正的数组或对象。

为什么需要它?因为实际开发中经常要“从一个对象里拿几个属性”“从一个数组里拿几个元素”,如果一个个写 obj.name、arr[0] 会很啰嗦。解构赋值就是把“取值的模式”写在等号左边,把真实数据写在等号右边。

怎么想?先别死记语法,先问:右边是什么数据?左边要创建哪些变量?数组解构按位置/索引对应,对象解构按属性名对应。怎么做?例如:

js
const user = { name: '张三', age: 18 };
const { name, age } = user;
console.log(name, age); // 张三 18

易错点:左边的大括号、中括号只是“结构/模式”,不是真正在创建一个对象或数组;右边必须是可解构的数据,不能把左边当成对象直接量。

二、对象解构:属性名负责匹配,冒号右边才是变量名 ​

为什么需要对象解构?对象属性多,按属性名取最清晰。怎么想?记住一句话:冒号左边是右边对象的属性名,冒号右边才是你自己起的变量名。例如:

js
const obj = {
  name: '高考证',
  address: ['上海', '北京']
};

const { name: userName, address } = obj;
console.log(userName); // 高考证
console.log(address);  // ['上海', '北京']

这里 name: userName 表示:去右边找 name 属性,把值赋给变量 userName;address 是简写,等价于 address: address。转写稿中通过 F12 验证变量值,说明分析结果和运行结果一致。

易错点:name 不是变量,userName 才是变量;属性名不能随便乱写,必须和右边对象能对应。若右边没有对应属性,变量得到 undefined。

三、简写与默认值:同名可省,缺属性可兜底 ​

为什么需要简写?因为属性名和变量名经常一样,写两遍多余。怎么想?当“属性名”和“变量名”一致时,只写一个即可:

js
const { number01, number02 } = { number01: 1000, number02: 2000 };

默认值则用于右侧数据可能缺属性。转写稿里强调:对象解构默认值与数组解构规则一致,但对象按属性名匹配,所以默认值变量不必像数组那样非放后边:

js
const {
  n1 = 100,
  n2 = 250,
  n3 = 300,
  n4
} = { n1: 100, n2: 250, n3: 300 };

console.log(n1, n2, n3, n4); // 100 250 300 undefined

简写和默认值也能混用:

js
const { n3 = 300 } = { n3: 300 };

易错点:默认值不是“有值也覆盖”;右侧没有该属性(或值为 undefined)时才用默认值。对象解构不按顺序匹配,所以默认值位置没有数组那样的限制。

四、复杂对象与函数传参:按需拆,不必全拆 ​

为什么需要?真实对象经常嵌套。怎么想?嵌套到哪里,就在模式里继续写对应结构;只解构自己想要的。怎么做:

js
const obj = {
  email: '[email protected]',
  names: ['n1', 'n2'],
  prop: { content: 'hello' }
};

const {
  email,
  names: [nu01, nu02],
  prop: { content }
} = obj;

这里真正解构出的变量是 email、nu01、nu02、content 四个;names、prop 只是匹配用的属性名,不是变量。转写稿中反复提醒这一点,并说可以用编辑器提示辅助判断。

函数传参也同理:形参写对象模式,调用时传对象:

js
function f({ name, age }) {
  console.log(name, age);
}
f({ name: '张三', age: 18 });

易错点:不传实参会报错,因为右边没有对象;可以传 {},缺的属性为 undefined;多传属性不影响,少传属性也不报错。转写稿中还演示了直接写 {...} = user 出现语法错误,后来加上 const 才正常,这说明课堂示例主要是在“声明变量并赋值”,不要把它和已有变量重新赋值的写法混在一起。

五、对象解构可解构“一切对象”,但别死记形式 ​

为什么需要?数组、字符串、内置对象也能按对象方式取属性。怎么想?右边只要是对象,就能按属性名取。怎么做:

js
const { length } = [1, 2, 3, 4, 5];
console.log(length); // 5

const { push, map } = [];
console.log(typeof push, typeof map); // function function

const { length: len, indexOf } = 'hello';
console.log(len, typeof indexOf); // 5 function

const { PI } = Math;
console.log(PI); // 3.1415926...

易错点:左边写大括号就是对象解构,不要因为右边是数组就误认为数组解构;取不到属性就是 undefined;null、undefined 不适合拿来解构。转写稿说“万事万物皆对象”是实际中的理解方式,核心是:对象解构按属性名取值,右边数据来源可以很多样,只取你需要的部分即可。

模板字符串:为什么需要多一种字符串写法 ​

单引号、双引号已经能定义字符串,为什么还要反引号?转写稿里先抓住目的:模板字符串不是替代字符串,而是给字符串增加一种更顺手的表示方式。它归根结底仍是字符串,typeof 结果不变。真正需要它,是因为旧写法遇到换行和变量拼接时很累:换行要写 \n,变量要用 + 一段段断开拼接。

怎么想:把反引号看成“能保留原样的字符串容器”。怎么做:用反引号包住内容,直接换行;用 ${} 插入变量或表达式。例如:

js
const msg = `hello world`;
const content = `锄禾日当午
汗滴禾下土
谁知盘中餐
粒粒皆辛苦`;

const name = '高晓乐';
const money = 100;
console.log(`我叫${name},计算结果是${money + 78 * 2}`);

易错点:模板字符串里的换行、缩进都会成为字符串内容;它和 HTML 对空白、换行的处理不是一回事,不要混为一谈。模板字符串里可以写单引号、双引号,但内容中要写反引号仍需转义。${} 里可以放变量,也可以放表达式,转写稿中就用 ${money + 78 * 2} 演示了运算。

用模板字符串生成 HTML:从数组到列表 ​

为什么需要:实际开发中常要把数组数据变成一段 HTML 结构。旧写法用单引号拼接,换行、缩进、变量都很麻烦。怎么想:先用 map 把每个数组元素变成一段模板字符串,得到新数组;再用 join('') 拼成一个完整字符串;最后赋给元素的 innerHTML。

怎么做:

js
const names = ['刘姥姥', '马姥姥', '毛姥姥', '司马姥姥', '欧阳姥姥'];

const html = names.map((item, index) => {
  return `<li>
    <span>${index + 1}</span>
    <a>${item}</a>
  </li>`;
}).join('');

document.querySelector('#box').innerHTML = html;

易错点:join() 默认会用逗号连接,生成 HTML 时要传空字符串 join(''),否则会多出逗号;map 返回的是新数组,不会直接改原数组;索引从 0 开始,展示序号时常写 index + 1。

ES5 字符串方法回顾:先有“有这个方法”的印象 ​

转写稿先回顾了 ES5 字符串实例方法:charAt 按索引取字符,charCodeAt 取 Unicode 编码,indexOf / lastIndexOf 判断出现位置,找不到返回 -1;截取有 slice、substring、substr,其中 substr 第二个参数是长度;大小写转换有 toUpperCase、toLowerCase;字符串拆数组用 split;正则相关有 search、match、replace。

为什么需要回顾:新方法不是孤立的,很多功能旧方法也能做,只是新方法语义更直接。怎么想:不要求死记参数细节,但脑子里要有“有这么个方法”的印象,细节查 MDN。易错点:indexOf 返回位置,不是布尔值;判断包含时旧写法常写 indexOf(...) !== -1。

ES6 新增方法:repeat、includes、startsWith、endsWith ​

repeat 用来重复字符串,返回新字符串,不修改原字符串:

js
const msg = 'hello world';
console.log(msg.repeat(3));

includes 判断是否包含某个值,返回布尔值;第二个参数是开始查找的位置。startsWith 判断是否以某值开头,第二个参数也是起始位置;endsWith 判断是否以某值结尾,但第二个参数表示“按多长来截取判断”,不是起始索引。转写稿中特别演示了 startsWith('hello') 为 true,从索引 1 开始判断则变成判断 ello...;endsWith 写长度 5 时只在前 5 个字符里判断结尾。

js
console.log(msg.includes('l'));       // true
console.log(msg.includes('l', 5));    // 从索引 5 开始找
console.log(msg.startsWith('hello')); // true
console.log(msg.endsWith('d'));       // true

易错点:方法名拼写要准确:includes 不是 include,startsWith 不是 star S with,endsWith 不是 endSwith;includes 第二参数是位置,endsWith 第二参数是长度,二者不能混。

padStart、padEnd、trimStart、trimEnd、replaceAll ​

padStart / padEnd 用来把字符串填充到指定长度,默认用空格,第二个参数可指定填充内容。它们返回新字符串,不改变原字符串。转写稿演示了 msg.padStart(20) 在前面补空格到 20 长度;用 '-' 或 '0' 可指定填充字符。易错点:填充内容按“字符串”计算长度,可能整组填充后被截断。

trim 去掉两端空格;trimStart 只去前面空格,trimEnd 只去后面空格。易错点:它们只处理空格,不处理中间空格,也不能指定去掉其他字符。

replace 默认只替换第一个匹配项;replaceAll 会替换所有匹配项。转写稿中把多个 l 全部替换,就是用 replaceAll 演示的。易错点:replaceAll 是较新方法,旧环境要注意兼容;replace 想全部替换通常要配合全局正则。

小结:记功能,不背细节 ​

字符串新增特性的共同点是:语义更直接、返回新值、不修改原字符串。学习时先问“为什么需要”,再记“怎么用”,最后通过文档确认参数。转写稿反复强调:不用记每个方法属于哪个版本,重点是知道有这个方法能解决什么问题,具体参数查 MDN。

先说明 ​

本节笔记标题写作“4 数值新增特性”,但转写稿实际讲的是对象解构赋值、模板字符串、字符串方法。下面按转写稿内容整理,不额外编造“数值新增特性”的内容。

对象解构赋值:按属性名取值 ​

为什么需要:数组解构按索引对应,对象没有稳定索引,需要按属性名把对象里的值取出来赋给变量。
怎么想:等号右边是真正的对象,等号左边是“对象结构”,用属性名匹配右边同名属性;冒号后才是新变量名。
怎么做:

js
const obj = {
  name: '高考证',
  address: ['上海'],
  info: { age: 18 }
};
const { name: userName, address, info: userInfo } = obj;

这里 userName 取 name 的值,address 取数组,userInfo 取嵌套对象。若属性名和变量名一致,可简写:const { address } = obj;。默认值写法:const { n2 = 250 } = obj;。函数传参也可解构:

js
function f({ name, age }) {
  console.log(name, age);
}
f({ name: '张三', age: 18 });

易错点:左边的大括号不是对象数据,而是解构语法;用 const 时不能对已声明变量重复声明,转写中直接复制旧写法导致语法错误,换变量名并加 const 后才正常;右边对象没有对应属性时得到 undefined,不会自动报错,除非后续使用出错。复杂嵌套中,names、prop 这类中间属性名只是匹配依据,不一定都会变成变量。

复杂对象与“一切皆对象”的解构 ​

为什么需要:真实数据常是嵌套对象、数组混合结构,只想取其中一部分。
怎么想:继续用“属性名匹配”的规则;数组本身也是对象,所以可用对象解构取 length、push 等属性。
怎么做:

js
const arr = [10, 20, 30];
const { length, push } = arr;
console.log(length); // 3
console.log(typeof push); // function

易错点:不要以为左边是 {} 就一定解构普通对象;右边可以是数组、字符串等,只要能按属性名找到值。中间属性名不是变量,别误数变量个数。

模板字符串:反引号与换行 ​

为什么需要:单双引号字符串写换行要 \n,拼接变量也麻烦。
怎么想:反引号字符串本质仍是字符串,但支持直接换行和插值。
怎么做:

js
const content = `锄禾日当午
汗滴禾下土`;
console.log(content);

易错点:模板字符串里的换行、缩进都会成为字符串内容;若输出到 HTML,还要按 HTML 规则处理,不能把 JS 字符串规则和 HTML 规则混在一起。模板字符串中写反引号仍需转义。

模板字符串插值与表达式 ​

为什么需要:替代繁琐的字符串拼接。
怎么想:用 ${} 放入变量或表达式,结果会被计算并转成字符串。
怎么做:

js
const name = '张三';
const money = 100;
const msg = `姓名:${name},金额:${money * 2}`;

生成列表时常配合 map 和 join(''):

js
const html = list.map((item, index) =>
  `<li><span>${index + 1}</span>${item}</li>`
).join('');
box.innerHTML = html;

易错点:join() 默认用逗号连接,生成 HTML 时要传空字符串;插值里可以写表达式,但不要把复杂逻辑硬塞进去。

字符串 ES5 方法回顾 ​

为什么需要:ES6 新方法建立在旧方法之上,先知道已有能力。
怎么想:按功能记:取字符、查位置、截取、大小写、分割、正则相关。
怎么做:charAt、charCodeAt、indexOf、lastIndexOf、slice、substring、substr、toUpperCase、toLowerCase、split、search、match、replace。
易错点:substring 第二个参数是结束位置,substr 第二个参数是长度;细节可查文档,但要知道“有这个方法”。

字符串 ES6 新增方法 ​

为什么需要:重复、包含判断、首尾判断、填充、去空格、全部替换等需求很常见。
怎么想:这些方法多返回新字符串或布尔值,不修改原字符串。
怎么做:

js
'哈'.repeat(3);              // '哈哈哈'
'hello'.includes('l');       // true
'hello'.startsWith('he');    // true
'hello'.endsWith('lo');      // true
'5'.padStart(3, '0');        // '005'
'5'.padEnd(3, '0');          // '500'
'  hi  '.trim();             // 'hi'
'  hi  '.trimStart();        // 'hi  '
'  hi  '.trimEnd();          // '  hi'
'a-b-a'.replaceAll('a', 'x');// 'x-b-x'

易错点:includes 第二个参数是开始查找位置;startsWith 第二个参数是开始位置;endsWith 第二个参数是“只检查前几个字符”的长度,不是开始位置;padStart/padEnd 第一个参数是目标总长度,第二个参数是填充内容;trim 只去两端空格,不能指定去除其他字符。

课堂画面 ​

课堂画面 1

课堂画面 2

课堂画面 3

课堂画面 4

课堂画面 5

课堂画面 6

代码示例 ​

示例 1:对象解构赋值(基础 / 改名 / 默认值 / 嵌套 / 函数传参) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>对象解构赋值</title>
</head>
<body>
  <script>
    // 1. 基础:按属性名匹配,冒号前是属性名,冒号后是自己起的变量名
    const obj = {
      name: '高晓乐',
      address: ['上海', '北京'],
      h: { name: '老李', value: 'abc' }
    };
    const { name: userName, address: addr, h: hValue } = obj;
    console.log(userName, addr, hValue); // 高晓乐  ['上海','北京']  {name:'老李',value:'abc'}

    // 2. 简写:属性名和变量名一样时,只写一个
    const user = { name: 'Jack', address: '上海', number: 1000 };
    const { name, address: a, number: b } = user; // name 简写,address/number 改名
    console.log(name, a, b); // Jack  上海  1000

    // 3. 默认值:右边没有对应属性时用默认值,没有默认值就是 undefined
    const { n1 = 100, n2 = 250, n3 = 300, n4 } = { n1: 100, n2: 250, n3: 300 };
    console.log(n1, n2, n3, n4); // 100  250  300  undefined

    // 4. 复杂对象:深入内部解构(email、nu01、nu02、content 共 4 个变量)
    const data = {
      email: '[email protected]',
      names: ['张一', '张二'],
      prop: { content: 'hello ES6' }
    };
    const { email, names: [nu01, nu02], prop: { content } } = data;
    console.log(email, nu01, nu02, content);

    // 5. 函数传参:实参传一个对象,形参位置写对象结构
    function fn({ name, age, like }) {
      console.log(name, age, like);
    }
    fn({ name: '高晓乐', age: 18, like: 'coding', extra: '多给属性不影响' }); // 多给不报错
    fn({ name: '高晓乐' }); // 少给 → undefined
    // fn();                // 报错:不传参相当于右边没写对象

    // 6. 一切皆对象:数组、字符串、Math 都能按对象结构解构
    const arr = [10, 20, 30, 40, 50];
    const { length, push, map } = arr;
    console.log(length, typeof push, typeof map); // 5  function  function

    const { length: len, indexOf, foo = '默认值' } = 'hello world';
    console.log(len, typeof indexOf, foo); // 11  function  默认值

    const { PI } = Math;
    console.log(PI); // 3.1415926...
  </script>
</body>
</html>

关键行与易错点

  • 对应规则:数组靠索引对应,对象靠属性名对应。左边大括号里的 name / names / prop 只是"匹配用的属性名",不是变量;真正创建变量的是冒号后面那部分。
  • 嵌套解构 names: [nu01, nu02] 中,names 本身不会变成变量,只有 nu01、nu02 是变量,这是本节最容易数错的地方。
  • 简写只适用于"属性名 === 变量名",写成 { name };一旦改名就必须写 { name: userName },否则拿不到值。
  • 对象解构的默认值不要求放在最后(因为不按顺序匹配),这点和数组解构不一样。
  • 转写稿强调:用 const / let 声明时,这种写法本质是"创建变量并赋值",不要指望先声明再单独解构赋值(语法结构上不支持);日常场景就是拿到对象后拆开取值,够用。
  • 右边可以是变量、直接量、表达式,只要是对象类型的数据即可;undefined/null 不能解构。

示例 2:模板字符串(换行 / 插变量 / 插表达式 / 拼 HTML) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>模板字符串</title>
  <style>
    #box ul { list-style: none; padding: 0; }
    #box li { display: flex; gap: 10px; line-height: 28px; }
    #box span { color: #f60; }
  </style>
</head>
<body>
  <div id="box"></div>
  <script>
    // 1. 反引号定义,本质还是字符串
    const msg = `锄禾日当午
汗滴禾下土
谁知盘中餐
粒粒皆辛苦`;
    console.log(typeof msg, msg); // string,且带着换行

    // 2. 插入变量:${变量名}
    const name = '高晓乐';
    const money = 1000;
    const info = `我叫${name},我有${money}元`;
    console.log(info);

    // 3. 插入表达式:里面可以直接算
    const total = `(${money} + 78) * 2 = ${(money + 78) * 2}`;
    console.log(total);

    // 4. 典型应用:拼 HTML 结构
    const names = ['刘姥姥', '马姥姥', '毛姥姥', '司马姥姥', '欧阳姥姥'];
    const html = names.map((item, index) => `
      <li>
        <span>${index + 1}</span>
        <a href="#">${item}</a>
      </li>
    `).join('');
    document.querySelector('#box').innerHTML = `<ul>${html}</ul>`;
  </script>
</body>
</html>

关键行与易错点

  • 反引号在 Tab 键上方;它和单引号、双引号是平级的字符串表示方式,所以 typeof 结果仍然是 string。
  • 直接写换行即可,不需要 \n;用单引号写换行会直接语法报错。
  • ${} 里既能放变量也能放表达式(${(money + 78) * 2}),不用再断开字符串做 + 拼接。
  • .map() 返回新数组,.join('') 把数组拼成一个字符串;不传 '' 会默认用逗号拼接,这是生成 HTML 时最常见的坑。
  • 模板字符串里的缩进和换行会原样保留成字符串内容;但把它塞进 innerHTML 后,HTML 对空白的处理规则与 JS 字符串不同,别把两者混为一谈。
  • 模板字符串内部不能直接写反引号,需要时用 &#96; 转义。

示例 3:字符串新增方法(repeat / includes / startsWith / endsWith / pad / trim / replaceAll) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>字符串新增方法</title>
</head>
<body>
  <script>
    // 1. repeat:重复,返回新字符串,不改变原字符串
    const str = '高晓乐';
    console.log(str.repeat(10));
    console.log(str); // 原字符串不变

    const msg = 'hello world'; // 长度 11

    // 2. includes:是否包含某个值,返回布尔值;第二个参数是起始位置
    console.log(msg.includes('l'));     // true
    console.log(msg.includes('world')); // true
    console.log(msg.includes('h', 5));  // false,从索引 5 开始往后找

    // 3. startsWith / endsWith:是否以某值开头 / 结尾
    console.log(msg.startsWith('hello'));     // true
    console.log(msg.startsWith('ello', 1));   // true,从索引 1 开始判断
    console.log(msg.endsWith('d'));           // true
    console.log(msg.endsWith('d', 5));        // false,只看前 5 个字符

    // 4. padStart / padEnd:填充到指定长度,返回新字符串
    console.log(msg.padStart(20));        // 前面补空格到 20 位
    console.log(msg.padStart(20, '*'));   // 前面补 * 到 20 位
    console.log(msg.padEnd(20, '0'));     // 后面补 0 到 20 位

    // 5. trim / trimStart / trimEnd:去掉两端 / 前面 / 后面的空格
    const content = '   hello world   ';
    console.log(`#${content.trim()}#`);      // #hello world#
    console.log(`#${content.trimStart()}#`); // #hello world   #
    console.log(`#${content.trimEnd()}#`);   // #   hello world#

    // 6. replace 只换第一个,replaceAll 换所有
    console.log('hello world'.replace('l', 'L'));    // heLlo world
    console.log('hello world'.replaceAll('l', 'L')); // heLLo worLd
  </script>
</body>
</html>

关键行与易错点

  • 这些都是字符串实例方法(定义在 String.prototype 上),直接用 str.xxx() 调用;全部是访问器方法,只返回新值,不修改原字符串。
  • padStart(n) 的 n 是总长度,不是"要补几个字符";第二个参数可以指定填充内容,多字符填充时可能被"拦腰截断"以凑够总长度。
  • startsWith 的第二个参数是起始索引;endsWith 的第二个参数是截取长度(只看前几个字符),两者含义不同,最容易记反。
  • includes 只返回布尔值;想拿位置还得用 indexOf / lastIndexOf(找不到返回 -1)。
  • trim 系列没有参数,只能去空格,不能指定去掉别的字符。
  • replace 不写全局正则只替换第一个,要全替换用 replaceAll(或 replace(/l/g, 'L'))。
  • 这些方法不必死记参数细节,记住"有这么一个方法能实现这个功能",具体参数查 MDN 即可。

常见错误 ​

  1. 现象:直接写 {a} = obj 报语法错误。→ 原因:语句开头被解析为块语句,不是解构表达式。→ 修法:对已声明变量加括号:({a} = obj);或重新用 const/let 声明。
  2. 现象:对象解构变量值错位。→ 原因:把对象解构当成数组解构,按顺序对应。→ 修法:明确对象按属性名匹配,写法用 {属性名: 变量名}。
  3. 现象:嵌套解构多出 names、address 等变量。→ 原因:把中间属性名误当绑定变量。→ 修法:中间键只作匹配,如 {names: [a, b]} 中 names 不是变量。
  4. 现象:默认值在 null 时没生效。→ 原因:解构默认值只在值为 undefined 时触发。→ 修法:需要兼容 null 时显式判断或另行赋默认值。
  5. 现象:模板字符串里写 {name} 或直接写 name,变量没替换。→ 原因:缺少插值语法。→ 修法:写成 ${name};表达式写 ${a + b}。
  6. 现象:replace('l', 'L') 只换第一个 l。→ 原因:replace 默认只替换首个匹配。→ 修法:用 replaceAll 或全局正则 /l/g。
  7. 现象:endsWith('d', 5) 结果与预期不符。→ 原因:第二个参数是“截取前 N 个字符的长度”,不是起始位置。→ 修法:与 startsWith/includes 的第二参数语义区分开。

练习 ​

  1. 对 {name:'张三', age:18, address:{city:'上海'&#125;&#125;,一行解构得到 name、age、city,且 age 默认值为 20。
    (答案:const {name, age = 20, address: {city&#125;&#125; = obj;)
  2. 函数 fn({name, age = 18}) 调用 fn({name:'李四'}),输出什么?
    (答案:name 为 李四,age 为 18)
  3. 用模板字符串和 map 生成 <li>1-刘姥姥</li> 形式的列表,最后如何拼成一个字符串?
    (答案:模板中写 ${index + 1}-${item},再用 join(''))
  4. 对 'hello world':判断是否以 'world' 结尾、是否包含 'lo'、从索引 6 开始是否包含 'o'。
    (答案:endsWith('world')、includes('lo')、includes('o', 6))

原视频对照 ​

#视频时长
1对象解构赋值0122:37
2对象解构赋值0216:19
3模板字符串20:24
4字符串ES5方法总结05:25
5字符串ES6新增方法0112:12
6字符串ES6新增方法0209:37

小结 ​

  1. 对象解构按属性名匹配,不按书写顺序匹配。
  2. 等号左边是“解构模式”,不是真正的对象/数组数据。
  3. 简写只在属性名与变量名一致时可用;默认值只对 undefined 生效。
  4. 已声明变量做对象解构时必须加括号,避免被当成块语句。
  5. 函数参数可直接写解构模式,实参要传对象;缺属性得到 undefined 或默认值。
  6. 模板字符串的核心是反引号、保留换行缩进、${} 插值;生成 HTML 后常配合 join('')。
  7. 字符串新增方法多为访问器方法,返回新值,不改变原字符串。
  8. 记方法功能优先,参数细节查文档;replace 与 replaceAll、startsWith 与 endsWith 的第二参数语义要分清。