ES6 课程概述②

news2024/11/25 10:36:14

文章目录

  • 更好的 Unicode 支持
  • 更多的字符串 API
  • 3-3. [扩展]正则中的粘连标记
  • 模板字符串
  • 3-5. [扩展]模板字符串标记
  • 4-1. 参数默认值
    • 使用
    • [扩展]对 arguments 的影响
    • [扩展]留意暂时性死区
  • 4-2. 剩余参数
  • 4-3. 展开运算符
    • 对数组展开 ES6
    • 对对象展开 ES7
    • 函数柯里化
  • 4-5. 明确函数的双重用途
  • 4-6. 箭头函数
    • 使用语法
    • 注意细节
    • 应用场景
    • 数组的扩展
      • 含义

更好的 Unicode 支持

早期,由于存储空间宝贵,Unicode 使用 16 位二进制来存储文字。我们将一个 16 位的二进制编码叫做一个码元(Code Unit)。

后来,由于技术的发展,Unicode 对文字编码进行了扩展,将某些文字扩展到了 32 位(占用两个码元),并且,将某个文字对应的二进制数字叫做码点(Code Point)。

ES6 为了解决这个困扰,为字符串提供了方法:codePointAt,根据字符串码元的位置得到其码点。

同时,ES6 为正则表达式添加了一个 flag: u,如果添加了该配置,则匹配时,使用码点匹配

更多的字符串 API

以下均为字符串的实例(原型)方法

  • includes

判断字符串中是否包含指定的子字符串

  • startsWith

判断字符串中是否以指定的字符串开始

  • endsWith

判断字符串中是否以指定的字符串结尾

  • repeat

将字符串重复指定的次数,然后返回一个新字符串。

3-3. [扩展]正则中的粘连标记

标记名:y

含义:匹配时,完全按照正则对象中的 lastIndex 位置开始匹配,并且匹配的位置必须在 lastIndex(默认为 0)位置。

模板字符串

ES6 之前处理字符串繁琐的两个方面:

  1. 多行字符串
  2. 字符串拼接

在 ES6 中,提供了模板字符串的书写,可以非常方便的换行和拼接,要做的,仅仅是将字符串的开始或结尾改为反引号 ` 符号

如果要在字符串中拼接 js 表达式,只需要在模板字符串中使用${JS表达式}

var love1 = "秋葵";
var love2 = "香菜";

var text = `邓哥喜欢${love1}
邓哥也喜欢${love2}
表达式可以是任何有意义的数据${1 + 3 * 2 / 0.5}
表达式是可以嵌套的:${`表达式中的模板字符串${love1 + love2}`}
\n\n
奥布瓦的发顺丰
在模板字符串中使用\${JS表达式}可以进行插值
`;

console.log(text);

3-5. [扩展]模板字符串标记

在模板字符串书写之前,可以加上标记:

标记名`模板字符串`;
var love1 = "秋葵";
var love2 = "香菜";

var text = myTag`邓哥喜欢${love1},邓哥也喜欢${love2}`;

//相当于:
// var text = myTag(["邓哥喜欢", ",邓哥也喜欢", "。"], "秋葵", "香菜")

function myTag(parts) {
  console.log(parts);
}

console.log(text);

在这里插入图片描述

标记是一个函数,函数参数如下:

  1. 参数 1:被插值分割的字符串数组
  2. 后续参数:所有的插值

模板字符串的实现原理:

var love1 = "秋葵";
var love2 = "香菜";

var text = myTag`邓哥喜欢${love1},邓哥也喜欢${love2}`;

function myTag(parts) {
  const values = Array.prototype.slice.apply(arguments).slice(1);
  // console.log(values);
  let str = "";
  for (let i = 0; i < values.length; i++) {
    str += `${parts[i]}${values[i]}`;
    if (i === values.length - 1) {
      str += parts[i + 1];
    }
  }
  return str;
}

4-1. 参数默认值

使用

在书写形参时,直接给形参赋值,附的值即为默认值

这样一来,当调用函数时,如果没有给对应的参数赋值(给它的值是 undefined),则会自动使用默认值。

function Point(x = 0, y = 0) {
  this.x = x;
  this.y = y;
}

const p = new Point();
p // { x: 0, y: 0 }

参数变量是默认声明的,所以不能用letconst再次声明。

function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
}

另外,一个容易忽略的地方是,参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101
上面代码中,参数p的默认值是x + 1。这时,每次调用函数foo,都会重新计算x + 1,而不是默认p等于 100。

与解构赋值默认值结合使用
参数默认值可以与解构赋值的默认值,结合起来使用。

function foo({x, y = 5}) {
  console.log(x, y);
}

foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined

[扩展]对 arguments 的影响

只要给函数加上参数默认值,该函数会自动变量严格模式下的规则:arguments 和形参脱离

[扩展]留意暂时性死区

形参和 ES6 中的 let 或 const 声明一样,具有作用域,并且根据参数的声明顺序,存在暂时性死区。

4-2. 剩余参数

arguments 的缺陷:

  1. 如果和形参配合使用,容易导致混乱
  2. 从语义上,使用 arguments 获取参数,由于形参缺失,无法从函数定义上理解函数的真实意图

ES6 的剩余参数专门用于收集末尾的所有参数,将其放置到一个形参数组中。

语法:

function (...形参名){

}

细节:

  1. 一个函数,仅能出现一个剩余参数
  2. 一个函数,如果有剩余参数,剩余参数必须是最后一个参数

4-3. 展开运算符

使用方式:...要展开的东西

在这里插入图片描述

/**
 * 对所有数字求和
 * @param  {...any} args
 */
function sum(...args) {
  let sum = 0;
  for (let i = 0; i < args.length; i++) {
    sum += args[i];
  }
  return sum;
}

/**
 * 获取一个指定长度的随机数组成的数组
 * @param {*} length
 */
function getRandomNumbers(length) {
  const arr = [];
  for (let i = 0; i < length; i++) {
    arr.push(Math.random());
  }
  return arr;
}

const numbers = getRandomNumbers(10);
//将数组的每一项展开,依次作为参数传递,而不是把整个数组作为一个参数传递
// sum(numbers)

console.log(sum(...numbers)); //相当于传递了10个参数
console.log(sum(1, 3, ...numbers, 3, 5));

对数组展开 ES6

const arr1 = [3, 67, 8, 5];

//克隆arr1数组到arr2

const arr2 = [0, ...arr1, 1];

console.log(arr2, arr1 === arr2);
//  [0, 3, 67, 8, 5, 1] false

对对象展开 ES7

const obj1 = {
  name: "成哥",
  age: 18,
  love: "邓嫂",
  address: {
    country: "中国",
    province: "黑龙江",
    city: "哈尔滨",
  },
};

// 浅克隆到obj2

const obj2 = {
  ...obj1,
  name: "邓哥",
};

console.log(obj2);

console.log(obj1.address === obj2.address); //true
// {name: '邓哥', age: 18, love: '邓嫂', address: {…}}address: {country: '中国', province: '黑龙江', city: '哈尔滨'}age: 18love: "邓嫂"name: "邓哥"[[Prototype]]: Object

// true

函数柯里化

function cal(a, b, c, d) {
  return a + b * c - d;
}
//curry:柯里化,用户固定某个函数的前面的参数,得到一个新的函数,新的函数调用时,接收剩余的参数
function curry(func, ...args) {
  //第一个参数是函数,第二个参数是乘余参数
  return function (...subArgs) {
    //返回一个函数(高阶函数),接收乘余参数
    const allArgs = [...args, ...subArgs]; //拼接参数
    if (allArgs.length >= func.length) {
      //判断参数与函数参数个数
      return func(...allArgs); //参数够了,执行函数
    } else {
      //参数不够,继续固定
      return curry(func, ...allArgs);
    }
  };
}

const newCal = curry(cal, 1, 2);

console.log(newCal(3, 4)); // 1+2*3-4
console.log(newCal(4, 5)); // 1+2*4-5
console.log(newCal(5, 6)); // 1+2*5-6
console.log(newCal(6, 7)); // 1+2*6-7

4-5. 明确函数的双重用途

ES6 提供了一个特殊的 API,可以使用该 API 在函数内部,判断该函数是否使用了 new 来调用

new.target
//该表达式,得到的是:如果没有使用new来调用函数,则返回undefined
//如果使用new调用函数,则得到的是new关键字后面的函数本身

function Person(firstName, lastName) {
    //判断是否是使用new的方式来调用的函数

    // //过去的判断方式
    // if (!(this instanceof Person)) {
    //     throw new Error("该函数没有使用new来调用")
    // }

    if (new.target === undefined) {
        throw new Error("该函数没有使用new来调用")
    }
    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = `${firstName} ${lastName}`;
}

const p1 = new Person("袁", "进");
console.log(p1)

4-6. 箭头函数

回顾:this 指向

  1. 通过对象调用函数,this 指向对象
  2. 直接调用函数,this 指向全局对象
  3. 如果通过 new 调用函数,this 指向新创建的对象
  4. 如果通过 apply、call、bind 调用函数,this 指向指定的数据
  5. 如果是 DOM 事件函数,this 指向事件源

使用语法

箭头函数是一个函数表达式,理论上,任何使用函数表达式的场景都可以使用箭头函数

完整语法:

(参数1, 参数2, ...)=>{
    //函数体
}

如果参数只有一个,可以省略小括号

(参数) => {};

const sum = (a, b) => ({
  a: a,
  b: b,
  sum: a + b,
});

console.log(sum(3, 5));

如果箭

注意细节

  • 箭头函数的函数体中的 this,取决于箭头函数定义的位置的 this 指向,而与如何调用无关
  • 箭头函数中,不存在 this、arguments、new.target,如果使用了,则使用的是函数外层的对应的 this、arguments、new.target
  • 箭头函数没有原型
  • 箭头函数不能作用构造函数使用

应用场景

  1. 临时性使用的函数,并不会可以调用它,比如:
    1. 事件处理函数
    2. 异步处理函数
    3. 其他临时性的函数
  2. 为了绑定外层 this 的函数
  3. 在不影响其他代码的情况下,保持代码的简洁,最常见的,数组方法中的回调函数
const obj = {
  count: 0,
  start: function () {
    setInterval(() => {
      this.count++;
      console.log(this);
    }, 1000);
  },
  regEvent: function () {
    window.onclick = () => {
      console.log(this);
    };
  },
  // 这里this不用解决
  print: function () {
    console.log(this);
    console.log(this.count);
  },
};

// 在函数里面用函数出现this指向问题
obj.start();
obj.regEvent();
obj.print();

在这里插入图片描述

数组的扩展

  • 扩展运算符
  • Array.from()
  • Array.of()
  • 数组实例的 copyWithin()
  • 数组实例的 find() 和 findIndex()
  • 数组实例的 fill()
  • 数组实例的 entries(),keys() 和 values()
  • 数组实例的 includes()
  • 数组实例的 flat(),flatMap()
  • 数组的空位
  • Array.prototype.sort() 的排序稳定性

含义

扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

注意,只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。

(...[1, 2])
// Uncaught SyntaxError: Unexpected number

console.log((...[1, 2]))
// Uncaught SyntaxError: Unexpected number

console.log(...[1, 2])
// 1 2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143958.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【菜菜的CV进阶之路 - 深度学习环境搭建】配置Ubuntu深度学习环境

六、配置Ubuntu深度学习环境 1、安装Google chrome 使用wget下载最新的Google Chrome .deb软件包&#xff1a; wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb更多地址可参考&#xff1a;在Deepin v20系统中下载和安装谷歌Chrome最新版de…

Vue学习笔记(一)

Vue学习笔记1. 什么是Vue2. 安装Vue2.1 使用独立版本2.2 使用CDN方式2.3 使用NPM方式3.Vue语法3.1 el挂载点3.2 data数据对象3.3 V-text 设置标签内的内容3.4 V-html3.5 V-on3.6 计数器3.7 v-show3.8 V-if3.9 v-bind3.10 v-for3.11 V-model4.class与style绑定5.表单输入绑定5.1…

【vue2】基础概念 01 (vue框架介绍、el、data、插值表达式)

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;vue框架介绍、结构元素详解&#xff08;el、data、插值表达式&#xff09; 目录&#xf…

《我是个怪圈》读书笔记

文章目录书籍信息论灵魂及其尺寸摇曳在恐惧与梦想之间的那只电灯泡&#xff08;取自拉塞尔埃德森的诗&#xff09;模式的因果潜力关于自我与符号副现象模式与可证性哥德尔的典型怪圈奇迹般步调划一的同步在公式与大整数之间翻转很大的整数与公式步调一致的移动质雅数怪圈论向下…

vue实现文件预览功能

目录 一、使用插件预览 1.前端实现在线预览文档 通过联机查看 Office 文档 打开新窗口预览文件 当前页面预览文件 注意事项 在创建好url之后&#xff0c;可能会出现无法打开文档的情况&#xff0c;这时候就需要对照官网的解释来查找问题了&#xff0c;官方文档的解释如下…

k线图入门精讲

K线图是贵金属技术分析的基础手段&#xff0c;刚入门的投资者应认真学习和理解k线的基础知识&#xff0c;因为有了认识才能分析。然而&#xff0c;多数上班族精力有限&#xff0c;无法耗费大量精力学习&#xff0c;今天小编就为准备了K线入门的“精读班”。 一、K线的作用 K线图…

【node.js】fs\path\http模块的使用 02

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;Node.js的fs\path\http模块的使用&#xff0c;模块化开发概念 目录 一、node.js概念与作…

Java程序员你自己的菜鸟气质霸气侧漏了吗?

对于刚入行的程序员来说&#xff0c;面对各种各样的陌生配置环境和代码库&#xff0c;难免会手忙脚乱&#xff0c;尽显菜鸟本色。 但从啥都需要教的菜鸟到啥都懂的大神程序员&#xff0c;并不简单&#xff0c;这需要牺牲一根又一根宝贵的头发&#xff0c;直到它们肉眼可数。 …

线上服务器CPU占用过高?7步带你搞定

一. 前言在Java开发岗位的面试中&#xff0c;时不时会出现一些运维类的题目&#xff0c;其实这也反映了后端面试的一种趋势。现在企业对后端开发的要求越来越全面&#xff0c;不仅要求我们会写代码&#xff0c;还要我们能够进行部署和运维。今天壹哥就结合一个真实的项目案例&a…

【Linux】Linux权限

权限的概念 限制人的&#xff0c;访问的对象天然可能没有这种“属性”权限&#xff1a;一件事情是否允许被谁“做”。 权限 人 事物属性 Linux上的用户分类 root&#xff0c;超级管理员&#xff0c;几乎可以干任何事情&#xff08;1个&#xff09;普通用户&#xff08;多个&a…

雷电飞机大战游戏|基于Java开发实现雷电飞机大战游戏

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

【前端】Vue项目:旅游App-(8)city:标签页Tabs动态数据:网络请求axios与request、数据管理store与pinia、各种封装

文章目录目标过程与代码安装相关库封装网络请求相关代码网络请求数据网络请求数据操作封装pinia管理数据并封装tab栏改为动态数据效果本篇总结总代码修改或新建的文件serviceindexmodules的cityrequest的configrequest的indexstoremodules的citymodules的loadingcity.vue参考目…

录屏没有声音怎么办?录屏怎么录声音

相信部分朋友在录制视频时&#xff0c;有出现录制视频没有声音&#xff0c;导致该段视频没有声音而无法播放。录屏怎么录声音&#xff1f;可以使用支持录制声音的专业的电脑录屏软件。今天小编就在这给大家分享在录制视频同时&#xff0c;将声音也录制进去的操作步骤。一、录屏…

【Linux】主函数的三个形参

主函数的形参有三个&#xff1a;argc参数个数&#xff0c;argv参数内容&#xff0c;envp环境变量。其中argc是整型&#xff0c;argv和envp是指针数组&#xff08;存的字符串&#xff09; argv源于我们自己在使用执行命令时传的内容&#xff0c;envp源于程序的父进程&#xff08…

力扣sql入门篇(十)

力扣sql入门篇(十) 1 查找重复的电子邮箱 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT Email FROM Person GROUP BY Email HAVING count(id)>21.3 运行截图 2 合作过至少三次的演员和导演 2.1 题目内容 2.1.1 基本题目信息 2.1.2 示例…

Java并发编程(六)ExecutorService

ExecutorService invokeAny() he invokeAll() 具有阻塞特性 invokeAny invokeAny 的作用是取得第一个完成任务的结果的值。 如果线程中增加 if (!Thread.currentThread().isInterrupted()) 判断&#xff0c;则会中断这些线程。 其他线程如果抛出 InterruptedException() 异常&a…

从徘徊迷茫到行业精英,社科院与杜兰大学金融管理硕士改变你的人生轨迹

在以“内卷”为主基调的职场环境里&#xff0c;似乎不停地进阶已经成为了职场人的唯一出路。但是&#xff0c;如何在进阶路上冲破职业瓶颈&#xff0c;到达心之所往的理想位置&#xff0c;则没有一个标准的答案。有的职场人士通过考取不同的技能证书来增加自身优势&#xff0c;…

Java Agent 踩坑之 appendToSystemClassLoaderSearch 问题

作者&#xff1a;卜比 本文是《容器中的 Java》系列文章之 2/n&#xff0c;欢迎关注后续连载 &#x1f603; 。 从 Java Agent 报错开始&#xff0c;到 JVM 原理&#xff0c;到 glibc 线程安全&#xff0c;再到 pthread tls&#xff0c;逐步探究 Java Agent 诡异报错。 背景 …

数据分析,你还在单纯地看数据?

企业的数字化意识越来越强&#xff0c;工作中也开始使用各种业务系统来管理业务&#xff0c;管理数据。很多人以为上了业务系统&#xff0c;对数据进行统计了&#xff0c;就是数据分析&#xff0c;这是大错特错的观点&#xff0c;数据分析是通过数据来剖析企业经营管理和业务发…

Using chatbots to scaffold EFL students argumentative writing (论文翻译)

使用聊天机器人来指导学生的议论文写作摘要研究表明&#xff0c;英语作为外语的学生的议论文写作受益于与同龄人的互动。然而&#xff0c;在实践中找到一个理想的对象很困难&#xff0c;聊天机器人被认为是这个问题的潜在解决方案。聊天机器人是人工智能的一种形式&#xff0c;…