Web前端:ES6是干什么的?(上)

2023-01-01 0 339

我们好,我来了!下期为我们增添的Web后端自学科学知识是”Web后端:ES6是干嘛的?(上)“,讨厌Web后端的爸爸妈妈,一同看一看吧!

主要就文本

ES6如是说Babel转A2P84PA基本上句法 数组方式统计数据扩充第一类扩充表达式扩充

自学最终目标

Web前端:ES6是干什么的?(上)

第二节 Babel转A2P84PA

1.1 ECMAScript 6 概要

自学邮箱:http://es6.ruanyifeng.com/

ECMAScript是javascript标准

ES6是ECMAScript的第6个版

ECMAScript 6.0(下列全称 ES6)是 JavaScript 词汇的新一代标准,早已在 2015 年 6 月正式宣布正式宣布发布了。它的最终目标,是使 JavaScript 词汇能用以撰写繁杂的小型插件,正式宣布成为虚拟化合作开发词汇。

1.1.1 ECMAScript 和 JavaScript 的亲密关系

ECMAScript是JavaScript的技术标准,JavaScript是ECMAScript的一类同时实现,在日常生活公开场合,这三个词是能交换的。

JavaScript的造物主Netscape子公司,将JavaScript递交给国际IECECMA,期望此种词汇能正式宣布成为国际标准,而后ECMA正式宣布发布国际LZSS的第三版(ECMA-262),明确规定了插件脚本词汇的标准,并将此种词汇称作ECMAScript

该标准从一已经开始是特别针对JavaScript词汇制订的,或许不叫JavaScript,有两个其原因:其一注册登记商标,Java是Sun子公司的注册登记商标,依照许可协定,多于Netscape子公司能不合法地采用JavaScript那个英文名字,且JavaScript这类也早已被Netscape子公司注册登记为注册登记商标;并有想充分体现尖萼词汇的决策者是ECMA,不是Netscape,有助于确保尖萼词汇的发展性和隐私权。

但实际上,JavaScript比ECMA-262的含义多得多,一个完整的JavaScript同时实现应该由下列三个部分组成:

1) ECMAScript:核心

2) DOM:文档第一类模型

3) BOM:插件第一类模型

1.1.2 ES6 与 ECMAScript 2015 的亲密关系

2011 年,ECMAScript 5.1 版正式宣布发布后,就已经开始制订 6.0 版了。因此,ES6 那个词的原意,是指 JavaScript 词汇的下一个版

标准委员会最终决定,标准在每年的 6 月份正式宣布正式宣布发布一次,作为当年的正式宣布版。接下来的时间,就在那个版的基础上做改动,直到下一年的 6 月份,草案就自然变成了新一年的版

1.1.3句法提案的批准流程

任何人都能向标准委员会(又称 TC39 委员会)提案,要求修改词汇标准。

一类新的句法从提案到变成正式宣布标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准。

Stage 0 – Strawman(展示阶段)Stage 1 – Proposal(征求意见阶段)Stage 2 – Draft(草案阶段)Stage 3 – Candidate(候选人阶段)Stage 4 – Finished(定案阶段)

一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式宣布标准里面

1.2 Babel转A2P84PA

Babel 是一个广泛采用的 ES6 转A2P84PA,能将 ES6 代码转为 ES5 代码,从而在现有环境执行。这意味着,你能用 ES6 的方式撰写程序,又不用担心现有环境是否支持

下面的命令在项目目录中,安装 Babel

1.npm install savedev @babel/core

2.配置配置文件.babelrc

该文件用以设置转码规则和插件,基本上格式如下。

{ “presets”: [], “plugins”: [] }

3.最新转码规则

npm install savedev @babel/presetenv

4.将这些规则加入.babelrc。

{ “presets”: [ “@babel/env”, “@babel/preset-react” ], “plugins”: [] }

5.命令行转码

Babel 提供命令行工具@babel/cli,用于命令行转码。

它的安装命令如下。

$ npm install savedev @babel/cli

6.基本上用法如下

# 转码结果输出到标准输出 $ npx babel example.js # 转码结果写入一个文件# outfile o 参数指定输出文件 $ npx babel example.js outfile compiled.js # 或者$ npx babel example.js o compiled.js # 整个目录转码# outdir d 参数指定输出目录 $ npx babel src outdir lib # 或者$ npx babel src d lib

npm: node page

Npx:

代码测试转码:

// 转码前input.map(item => item + 1); // 转码后input.map(function (item) { return item + 1;});

转码后

“use strict”;

input.map(function (item) {

return item + 1;

});

严格模式:严格模式,在表达式内部选择进行较为严格的全局或局部的错误条件检测,采用严格模式的好处是能提早知道代码中的存在的错误,

及时捕获一些可能导致编程错误的ECMAScript行为。在合作开发中采用严格模式能帮助我们早发现错误

1.3 let 和const 声明

ES6 新增了let命令,用以声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

1.3.1 let块级作用域

{ var num=10; let count=10; } console.log(num) console.log(count);//: count is not defined var arr=[10,20,30,40]; for(var i=0;i<arr.length;i++){ arr[i]=function(){ console.log(i) } } arr[2]();//4 //闭包 var arr=[10,20,30,40]; for(var i=0;i<arr.length;i++){ arr[i]=(function(i){ return function(){ console.log(i) } })(i); } arr[2]();//2 var arr=[10,20,30,40]; for(let i=0;i<arr.length;i++){//{let i=0} {let i=1} … arr[i]=function(){ console.log(i) } } arr[2]();//4

1.3.2不存在变量提升

var命令会发生“变量提升”现象,即变量能在声明之前采用,值为undefined。此种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才能采用。

为了纠正此种现象,let命令改变了句法行为,它所声明的变量一定要在声明后采用,否则报错

// var 的情况console.log(foo); // 输出undefinedvar foo = 2;// let 的情况console.log(bar); // 报错ReferenceErrorlet bar = 2;

上面代码中,变量foo用var命令声明,会发生变量提升,即脚本已经开始运行时,变量foo早已存在了,但是没有值,所以会输出undefined。变量bar用let命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误。

1.3.3不允许重复声明

let不允许在相同作用域内,重复声明同一个变量。

// 报错function func() { let a = 10; var a = 1;} // 报错function func() { let a = 10; let a = 1;}

1.3.4 为什么需要块级作用域

ES5 多于全局作用域和表达式作用域,没有块级作用域,这增添很多不合理的场景。

第一类场景,内层变量可能会覆盖外层变量

var uname=jack; function change(){ console.log(uname); var uname=rose; console.log(uname); } change();

其原因在于变量提升,导致内层的uname变量覆盖了外层的uname变量。

第二种场景,用以计数的循环变量泄露为全局变量。

var s = hello; for (var i = 0; i < s.length; i++) { console.log(s[i]);} console.log(i); // 5

上面代码中,变量i只用以控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。

1.4 const 命令

基本上用法

const声明一个只读的常量。一旦声明,常量的值就不能改变。

const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.

上面代码表明改变常量的值会报错。

const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

const foo; // SyntaxError: Missing initializer in const declaration

上面代码表示,对于const来说,只声明不赋值,就会报错。

固定方式

const setName = function(){ }

常量写法:const 声明数组常量的时候 一般数组全部大写

const NAME=’hello’

什么时候采用const? 什么时候采用let

只要你所声明的值不发生改变,采用常量,其他采用let

Const setName=function(){}

const obj={}

后面会慢慢接触到 更多的采用场景

总结:let具有块级作用域 不允许重复声明 不允许变量提升 那个var不具备的

本章作业

Es6与javascript区别

Let var const区别

第二节 Es6基本上句法

2.1变量的解构赋值

2.1.1数组的解构赋值

ES6 允许按照一定模式,从数组和第一类中提取值,对变量进行赋值,这被称作解构(Destructuring)。

以前,为变量赋值,只能直接指定值。

let a = 1;let b = 2;let c = 3;

ES6 允许写成下面这样。

let [a, b, c] = [1, 2, 3];

上面代码表示,能从数组中提取值,按照对应位置,对变量赋值。

本质上,此种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些采用嵌套数组进行解构的例子。

let [foo, [[bar], baz]] = [1, [[2], 3]];

.

let [ , , third] = [“foo”, “bar”, “baz”]; third // “baz”let [x, , y] = [1, 2, 3];

.

var [x,y]=[1,2]; console.log(x); var [x,y,m]=[3,4]; console.log(m);//undefind var [x,y]=[80,90,100];var [m,,,n]=[11,22,33,44]; console.log(m) var [x,y,[m,n]]=[10,20,[30,40]] console.log(m)

默认值

解构赋值允许指定默认值。

let [foo = true] = []; foo // true let [x, y = b] = [a]; // x=a, y=b let [x, y = b] = [a, undefined]; // x=a, y=b

2.1.2 第一类的解构赋值

let { foo, bar } = { foo: aaa, bar: bbb }; foo // “aaa”bar // “bbb”

第一类的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而第一类的属性没有次序,变量必须与属性同名,才能取到正确的值。

let { bar, foo } = { foo: aaa, bar: bbb }; foo // “aaa” bar // “bbb” let { baz } = { foo: aaa, bar: bbb }; baz // undefined

上面代码的第一个例子,等号左边的三个变量的次序,与等号右边三个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致取不到值,最后等于undefined。

如果解构失败,变量的值等于undefined。

let {foo} = {bar: baz}; foo // undefined

上面代码中,等号右边的第一类没有foo属性,所以变量foo取不到值,所以等于undefined。

第一类的解构赋值,能很方便地将现有第一类的方法,赋值到某个变量

默认值

第一类的解构也能指定默认值。

var {x = 3} = {}; x // 3var {x, y = 5} = {x: 1}; x // 1y // 5

2.1.3数组的解构赋值

数组也能解构赋值。这是因为此时,数组被转换成了一个类似数组的第一类。

const [a, b, c, d, e] = hello; a // “h”b // “e”c // “l”d // “l”e // “o”

类似数组的第一类都有一个length属性,因此还能对那个属性解构赋值。

let {length : len} = hello; len // 5

表达式参数的解构赋值

2.1.4 表达式的参数也能采用解构赋值。

function add([x, y]){ return x + y;} add([1, 2]); // 3

上面代码中,表达式add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于表达式内部的代码来说,它们能感受到的参数是x和y

function demo([x,y]){ return x+y; } console.log(demo([10,20])); function demo([x,y=30]){ return x+y; } console.log(demo([10])); function demo(x,y=20){ return x+y; } console.log(demo(10)

2.1.5 解构赋值用途

(1)交换变量的值

let x = 1;let y = 2; [x, y] = [y, x];

上面代码交换变量x和y的值,这样的写法不仅简洁,而且易读,语义非常清晰

面试题:

请用一句代码,同时实现三个统计数据值交换?

(2)提取 JSON 统计数据

解构赋值对提取 JSON 第一类中的统计数据,尤其有用。

let jsonData = { id: 42, status: “OK”, data: [867, 5309]}; let { id, status, data: number } = jsonData; console.log(id, status, number); // 42, “OK”, [867, 5309]

(3)表达式参数的默认值

jQuery.ajax = function (url, { async = true, beforeSend = function () {}, cache = true, complete = function () {}, crossDomain = false, global = true, // … more config} = {}) { // … do stuff};

解构赋值:

后面采用react采用方便:

var state={ flag:true, msg:ok } var {flag,msg}=state; console.log(flag,msg)

ES6 加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。

2.2数组的扩充

2.2.1字符的 Unicode 表示法

“\u0061” // “a”

但是,此种表示法只限于码点在\u0000~\uFFFF之间的字符。超出那个范围的字符,必须用三个双字节的形式表示。

“\uD842\uDFB7” // “”\u20BB7” // ” 7″

2.2.2数组的遍历器接口

ES6 为数组添加了遍历器接口(详见《Iterator》一章),使字符串能被for…of循环遍历。

for (let codePoint of foo) { console.log(codePoint)} // “f”// “o”// “o”

除了遍历数组,那个遍历器最大的优点是能识别大于0xFFFF的码点,传统的for循环无法识别这样的码点。

2.2.3模板数组 (重点)

传统的 JavaScript 词汇,输出模板通常是这样写的(下面采用了 jQuery 的方式)。

$(#result).append( There are <b> + basket.count + </b> + items in your basket, + <em> + basket.onSale + </em> are on sale!); 上面此种写法相当繁琐不方便ES6 引入了模板数组解决那个问题 $(#result).append(` There are <b>${basket.count}</b> items in your basket, <em>${basket.onSale}</em> are on sale! `);

2.3数组的新增方式

实例方式:includes(), startsWith(), endsWith()

实例方式:repeat()

实例方式:padStart(),padEnd()

实例方式:trimStart(),trimEnd()

2.3.1 includes(), startsWith(), endsWith()

传统上,JavaScript 多于indexOf方式,能用以确定一个数组是否包含在另一个数组中。ES6 又提供了三种新方式。

includes():返回布尔值,表示是否找到了参数数组。startsWith():返回布尔值,表示参数数组是否在原数组的头部。endsWith():返回布尔值,表示参数数组是否在原数组的尾部。
let s = Hello world!; s.startsWith(Hello) // true s.endsWith(!) // true s.includes(o) // true

这三个方式都支持第二个参数,表示已经开始搜索的位置。

let s = Hello world!; s.startsWith(world, 6) // true s.endsWith(Hello, 5) // true s.includes(Hello, 6) // false

上面代码表示,采用第二个参数n时,endsWith的行为与其他三个方式有所不同。它特别针对前n个字符,而其他三个方式特别针对从第n个位置直到数组结束。

2.3.2 实例方式:repeat()

repeat方式返回一个新数组,表示将原数组重复n次。

x.repeat(3) // “xxx” hello.repeat(2) // “hellohello” na.repeat(0) // “”

参数如果是小数,会被取整。

na.repeat(2.9) // “nana”

2.3.3 padStart(),padEnd()

ES2017 引入了数组补全长度的功能。如果某个数组不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

x.padStart(5, ab) // ababx x.padStart(4, ab) // abax x.padEnd(5, ab) // xabab x.padEnd(4, ab) // xaba

上面代码中,padStart()和padEnd()一共接受三个参数,第一个参数是数组补全生效的最大长度,第二个参数是用以补全的数组。

如果原数组的长度,等于或大于最大长度,则数组补全不生效,返回原数组。

2.3.4 trimStart(),trimEnd()

ES2019对数组实例新增了trimStart()和trimEnd()这三个方式。它们的行为与trim()一致,trimStart()消除数组头部的空格,trimEnd()消除尾部的空格。它们返回的都是新数组,不会修改原始数组。

const s = abc ; s.trim() // “abc” s.trimStart() // “abc ” s.trimEnd() // ” abc”

上面代码中,trimStart()只消除头部的空格,保留尾部的空格。trimEnd()也是类似行为。

第三节 数组扩充

* 扩充运算符

* 1.合并数组:concat

* 2.求数组中最大值

*

* Array.from() : 将类数组转化为真实的数组

* arguments、nodelist

3.1 数组扩充

var arr = [10,20,30] var arr1 = [40,50,60]; console.log([…arr,…arr1]); var arr2 = [23,235,2,3,52,35]; console.log(Math.max.apply(null,arr2)); console.log(Math.max(…arr2))

3.2Array.from() : 将类数组转化为真实的数组

Array.from方式用于将两类第一类转为真正的数组:类似数组的第一类(array-like object)和可遍历(iterable)的第一类(包括 ES6 新增的统计数据结构 Set 和 Map)。

下面是一个类似数组的第一类,Array.from将它转为真正的数组。

function hello(){ arguments = Array.from(arguments); console.log(Array.isArray(arguments)); } hello(1,2,3,4); var lists = document.getElementsByTagName(“li”); lists = Array.from(lists); console.log(lists); // push // arr.push // Array.isArray(arr);

3.3 Array.of()

Array.of方式用于将一组值,转换为数组。

Array.of(3, 11, 8) // [3,11,8]Array.of(3) // [3]Array.of(3).length // 1

那个方式的主要就目的,是弥补数组构造表达式Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。

Array() // []Array(3) // [, , ,]Array(3, 11, 8) // [3, 11, 8]

上面代码中,Array方式没有参数、一个参数、三个参数时,返回结果都不一样。多于当参数个数不少于 2 个时,Array()才会返回由参数组成的新数组

3.4数组实例的 copyWithin()

数组实例的copyWithin()方式,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,采用那个方式,会修改当前数组。

Array.prototype.copyWithin(target, start = 0, end = this.length)

它接受三个参数。

target(必需):从该位置开始替换统计数据。如果为负值,表示倒数。start(可选):从该位置已经开始读取统计数据,默认为 0。如果为负值,表示从末尾已经开始计算。end(可选):到该位置前停止读取统计数据,默认等于数组长度。如果为负值,表示从末尾已经开始计算。

这三个参数都应该是数值,如果不是,会自动转为数值。

[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]

.

// 将3号位复制到0号位[1, 2, 3, 4, 5].copyWithin(0, 3, 4)// [4, 2, 3, 4, 5] // -2相当于3号位,-1相当于4号位[1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5]

3.5 数组实例的 find() 和 findIndex()

数组实例的find方式,用于找出第一个符合条件的数组成员。它的参数是一个回调表达式,所有数组成员依次执行该回调表达式,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。

[1, 4, 5, 10].find((n) => n < 0) // -5

数组实例的 fill()

fill方式采用给定值,填充一个数组。

[a, b, c].fill(7) // [7, 7, 7]new Array(3).fill(7) // [7, 7, 7]

上面代码表明,fill方式用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。

fill方式还能接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

[a, b, c].fill(7, 1, 2) // [a, 7, c]

上面代码表示,fill方式从 1 号位已经开始,向原数组填充 7,到 2 号位之前结束。

注意,如果填充的类型为第一类,那么被赋值的是同一个内存地址的第一类,而不是深拷贝第一类。

for (let index of [a, b].keys()) { console.log(index);} // 0// 1for (let elem of [a, b].values()) { console.log(elem);} // a// bfor (let [index, elem] of [a, b].entries()) { console.log(index, elem);} // 0 “a”

第四节第一类的扩充

属性的简洁表示法

var name = “iwen”; var age = 20; const ADD = “add”; var obj = { name, // name:name age, [ADD]:function(){ console.log(“add”); }, fn1:function(){ }, fn2(){ console.log(“fn2”); } }

属性名表达式

JavaScript 定义第一类的属性,有两种方式。

// 方式一obj.foo = true; // 方式二obj[a + bc] = 123;

上面代码的方式其一直接用标识符作为属性名,方式并有用表达式作为属性名,这时要将表达式放在方括号之内。

ES6 允许字面量定义第一类时,用方式二(表达式)作为第一类的属性名,即把表达式放在方括号内。

let propKey = foo; let obj = { [propKey]: true, [a + bc]: 123};

下面是另一个例子。

let lastWord = last word; const a = { first word: hello, [lastWord]: world}; a[first word] // “hello”a[lastWord] // “world”a[last word] // “world”

表达式还能用于定义方式名。

4.2 第一类新增方式

Object.is()

ES5 比较三个值是否相等,多于三个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换统计数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一类运算,在所有环境中,只要三个值是一样的,它们就应该相等。

ES6 提出“Same-value equality”(同值相等)算法,用以解决那个问题。Object.is是部署那个算法的新方式。它用以比较三个值是否严格相等,与严格比较运算符(===)的行为基本上一致。

Object.is(foo, foo) // trueObject.is({}, {})// false

不同之处多于三个:其一+0不等于-0,并有NaN等于自身。

+0 === -0 //trueNaN === NaN // false

Object.is(+0, 0) // falseObject.is(NaN, NaN) // true

下期为我们增添的Web后端自学科学知识”Web后端:ES6是干嘛的?(上)“如是说完毕了,想了解更多文本的爸爸妈妈,关注我,更多文本等你看,我们下期再见!

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务