es6总结
往期文章
1.es6简介
-
回顾javascrip组成:
-
核心(ECMAScript)
由ECMA-262定义的ECMAScript是一种在国际认可的标准的脚本语言规范,与Web浏览器没有依赖关系。
-
文档对象模型(DOM)
DOM(文档对象模型)是 HTML 和 XML 的应用程序接口(API)。DOM 将把整个页面规划成由节点层级构成的文档。HTML或XML页面中的每个组成部分都是某种类型的节点,这些节点又包含着不同类型的数据。
-
浏览器对象模型(BOM)
E 3.0 和 Netscape Navigator 3.0 提供了一种特性 - BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的操作。
-
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
2.es6转码
- 转码原因:现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成ES5的语法。
浏览器es6支持度测试:ruanyf.github.io/es-checker
-
建立工程目录:
先建立一个项目的工程目录,并在目录下边建立两个文件夹:src和dist
src:书写ES6代码的文件夹,写的js程序都放在这里。
dist:利用Babel编译成的ES5代码的文件夹,在HTML页面需要引入的时这里的js文件。
-
编写index.html:
文件夹建立好后,我们新建一个index.html文件,需要注意的是index.html在引入js文件时,引入的是dist目录下的文件。
-
Babel 转码器:
-
npm init -y 先初始化我们的项目,-y代表全部默认同意,就不用一次次按回车了。命令执行完成后,会在项目根目录下生产package.json文件,可以根据自己的需要进行修改,比如我们修改name的值```
//package.json文件
{
"name": "es6",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
} npm install -g babel-cli 全局安装Babel-cli
-
npm install --save-dev babel-preset-es2015 babel-cli 本地安装babel-preset-es2015 和 babel-cli
成功后package.json文件多了devDependencies选项
{ "name": "es6", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-cli": "^6.26.0", "babel-preset-es2015": "^6.24.1" } }
- 新建.babelrc 在根目录下新建.babelrc文件,并打开录入下面的代码
{ "presets":[ "es2015" ], "plugins":[] }
-
babel src/index.js -o dist/index.js ES6成功转化为ES5的命令
转换后:
//es6 目录src/index.js let a=1; console.log(a); //es5 目录dist/index.js "use strict"; var a = 1; console.log(a);
-
简化转化命令
- 修改package.json文件
{ "name": "es6", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "babel src/index.js -o dist/index.js" //更换指令 }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-cli": "^6.26.0", "babel-preset-es2015": "^6.24.1" } }
-
npm run build 转码指令
npm run XXX
是执行配置在package.json中的脚本
-
3.变量声明
-
let声明
-
块级作用域
{ let a = 10; var b = 1; } a // 报错: a is not defined. b // 1 var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
分析:在var声明的循环中,在全局范围内都有效,所以全局只有一个变量
i
。每一次循环,变量i
的值都会发生改变,而循环内被赋给数组a
的函数内部的console.log(i)
,里面的i
指向的就是全局的i
。在let声明的循环中:变量
i
是let
声明的,当前的i
只在本轮循环有效,所以每一次循环的i
其实都是一个新的变量,所以最后输出的是6
-
声明变量不能提升
// var 的情况 console.log(foo); // 输出undefined var foo = 2; // let 的情况 console.log(bar); // 报错ReferenceError let bar = 2;
且let不能提升和块级的特性,导致暂时性死区
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
区块中存在
let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。 -
不允许重复声明
// 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; } function func(arg) { let arg; // 报错 } function func(arg) { { let arg; // 不报错 } }
块级作用域的需求场景
-
内层变量可能会覆盖外层变量。
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'hello world'; } } f(); // undefined
f()方法内定义的tmp变量提升,覆盖外部的变量,所有undefined
-
用来计数的循环变量泄露为全局变量
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
循环结束后i并没有消失,而是变成了全局变量
-
-
const声明
-
定义:
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
- 性质:块级作用域、不可变量提升、短暂死区、不可重复声明
-
定义:
-
小知识:javascript6种变量声明
var
命令、function
命令、let
和const
命令、import
命令和class
命令
4.解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
- 数组解构赋值
//基础用法
let [a, b, c] = [1, 2, 3];
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
//不完全解构,解构不成功,变量的值就等于undefined
let [foo] = []; //foo的值undefined
let [bar, foo] = [1]; //foo的值undefined
//解构设置默认值
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'</pre>
-
对象解构赋值
与数组解构不同点:数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: "aaa", bar: "bbb" }; foo // "aaa" bar // "bbb" let { baz } = { foo: "aaa", bar: "bbb" }; baz // undefined
-
字符串结构
const [a,b,c,d,e,f]="fengai";
console.log(a);//f
console.log(b);//e
console.log(c);//n
console.log(d);//g
console.log(e);//a
console.log(f);//i
-
函数解构
//函数数组解构
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
//函数对象解构
let json = {
a:'xiao',
b:'feng'
}
function fun({a,b='ha'}){//默认b='ha'
console.log(a,b);
}
fun(json);
-
圆括号使用
如果在解构之前就定义了变量,这时候你再解构,编译会报错
//不使用圆括号
let {foo} ={foo:'JSPang'};
//使用圆括号
let foo;
({foo} ={foo:'JSPang'});
console.log(foo); //控制台输出jspang
5.字符串扩展
-
for...of 字符串遍历
for (let codePoint of 'foo') { console.log(codePoint) } // "f" // "o" // "o"
-
includes(), startsWith(), endsWith()
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!'; s.startsWith('Hello') // true s.endsWith('!') // true s.includes('o') // true
-
repeat() 字符串重复次数
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
-
字符串模板
//之前版本
let jspang='字符串';
let blog = '原来'+jspang+'拼接';
//es6版本
let jspang='字符串';
let blog = '原来${jspang}拼接';
//支持运算
let a=1;
let b=2;
let result=`${a+b}`;//3
6.正则扩展
-
String.prototype.matchAll
可以一次性取出所有匹配。不过,它返回的是一个遍历器(Iterator),而不是数组。
const string = 'test1test2test3';
// g 修饰符加不加都可以
const regex = /t(e)(st(\d?))/g;
for (const match of string.matchAll(regex)) {
console.log(match);
}
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
7.数值的扩展
-
二进制、八进制表达
二进制和八进制数值的新的写法,分别用前缀
0b
(或0B
)和0o
(或0O
)表示。0b111110111 === 503 // true 0o767 === 503 // true
-
Number.isFinite(), Number.isNaN()
Number.isFinite()
用来检查一个数值是否为有限的(finite),即不是Infinity
Number.isNaN()
用来检查一个值是否为NaN
。
Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false</pre>
-
Number.parseInt(), Number.parseFloat()
ES6 将全局方法
parseInt()
和parseFloat()
,移植到Number
对象上面,行为完全保持不变。
// ES5的写法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45
// ES6的写法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45</pre>
-
Number.isInteger()
Number.isInteger()
用来判断一个数值是否为整数。Number.isInteger(25) // true Number.isInteger(25.1) // false</pre>
-
安全整数和 Number.isSafeInteger()
JavaScript 能够准确表示的整数范围在
-2^53
到2^53
之间(不含两个端点),超过这个范围,无法精确表示这个值。最大安全数:
Number.MAX_SAFE_INTEGER
最小安全数:
Number.MIN_SAFE_INTEGER
-
Number.isSafeInteger() :
判断一个数是否为安全数
Number.isSafeInteger('a') // false Number.isSafeInteger(null) // false Number.isSafeInteger(NaN) // false Number.isSafeInteger(Infinity) // false Number.isSafeInteger(-Infinity) // false Number.isSafeInteger(3) // true Number.isSafeInteger(1.2) // false Number.isSafeInteger(9007199254740990) // true Number.isSafeInteger(9007199254740992) // false Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false
8.Math对象的扩展
-
Math.trunc() 数字取整数
-
Math.sign() 判断一个数是否为正数、负数、0
参数为正数,返回
+1
;参数为负数,返回
-1
;参数为 0,返回
0
;参数为-0,返回
-0
;其他值,返回
NaN
。 -
Math.cbrt() 计算一个数的立方根。
-
Math.hypot() 返回所有参数的平方和的平方根。
Math.hypot(3, 4); // 5 Math.hypot(3, 4, 5); // 7.0710678118654755 Math.hypot(); // 0 Math.hypot(NaN); // NaN Math.hypot(3, 4, 'foo'); // NaN Math.hypot(3, 4, '5'); // 7.0710678118654755 Math.hypot(-3); // 3
9.函数的扩展
-
函数参数设置默认值
function log(x, y = 'World') { console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello
-
函数的 length 属性
指定了默认值以后,函数的
length
属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length
属性将失真。(function (a) {}).length // 1 (function (a = 5) {}).length // 0 (function (a, b, c = 5) {}).length // 2</pre>
同理,后文的
rest 参数
也不会计入length
属性。 -
rest 参数
rest 参数(形式为
...变量名
),用于获取函数的多余参数,这样就不需要使用arguments
对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
rest是真数组
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
//剩余参数
function feng(first,...arg){
for(let val of arg){
console.log(val); //1,2,3,4,5,6,7
}
}
feng(0,1,2,3,4,5,6,7);
-
arguments回顾
arguments
对象不是数组,而是一个类似数组的对象,伪数组
arguments.length 参数个数
arguments[0] 第一个参数,...
转换成真数组:
function arg2arr(){ var arr = Array.prototype.slice.call(arguments); console.log(arr); } arg2arr(1,2,3);
-
name 属性
函数的
name
属性,返回该函数的函数名。function foo() {} foo.name // "foo"</pre>
-
箭头函数
函数体内的
this
对象,就是定义时所在的对象,而不是使用时所在的对象。不可以当作构造函数,也就是说,不可以使用
new
命令,否则会抛出一个错误。不可以使用
arguments
对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
var f = () => 5; // 等同于 var f = function () { return 5 }; var sum = (num1, num2) => num1 + num2; // 等同于 var sum = function(num1, num2) { return num1 + num2; }; //多个代码段用{} var sum = (num1, num2) => { console.log("feng"); return num1 + num2; }
-
函数体中的严格模式
我们在ES中就经常使用严谨模式来进行编程,但是必须写在代码最上边,相当于全局使用。在ES6中我们可以写在函数体中,相当于针对函数来使用。
function add(a,b=1){ 'use strict' if(a == 0){ throw new Error('This is error'); } return a+b; } console.log(add(1));
-
双冒号运算符
函数绑定运算符是并排的两个冒号(
::
),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this
对象),绑定到右边的函数上面。(可替代apply,call,bind)foo::bar; // 等同于 bar.bind(foo); foo::bar(...arguments); // 等同于 bar.apply(foo, arguments); const hasOwnProperty = Object.prototype.hasOwnProperty; function hasOwn(obj, key) { return obj::hasOwnProperty(key); }
10.数组的扩展
-
扩展运算符
扩展运算符(spread)是三个点(
...
)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列console.log(...[1, 2, 3]) // 1 2 3 console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5 [...document.querySelectorAll('div')] // [<div>, <div>, <div>] //替代apply,将数组分解成一个个函数参数 // ES5 的写法 function f(x, y, z) { // ... } var args = [0, 1, 2]; f.apply(null, args); // ES6的写法 function f(x, y, z) { // ... } let args = [0, 1, 2]; f(...args);
-
复制数组
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。
const a1 = [1, 2]; const a2 = a1;//传址而非传值 a2[0] = 2; a1 // [2, 2] //改变a2会影响a1的值
...扩运算克隆
const a1 = [1, 2]; // 写法一 const a2 = [...a1]; // 写法二</pre>
-
合并数组
const arr1 = ['a', 'b']; const arr2 = ['c']; const arr3 = ['d', 'e']; // ES5 的合并数组 arr1.concat(arr2, arr3); // [ 'a', 'b', 'c', 'd', 'e' ] // ES6 的合并数组 [...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ]
-
与解构赋值结合
// ES5 a = list[0], rest = list.slice(1) // ES6 [a, ...rest] = list
-
字符串
[...'hello'] // [ "h", "e", "l", "l", "o" ]</pre>
-
-
Array.from() 将伪数组转化为真数组
//伪数组: 1、伪数组是一个对象 2、这个对象必须要有length属性 3、如果这个对象的length不为0,那么必须要有按照下标存储的数据 let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 }; // ES5的写法 var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']; // ES6的写法 let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']; / arguments对象 function foo() { var args = Array.from(arguments); // ... }
-
Array.of() 将一组值,转换为数组
Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1
-
find() 和 findIndex()实例方法
find(): 用于找出
第一个
符合条件的数组成员。回调函数参数依次为
当前的值
、当前的位置
和原数组
find(function(value, index, arr) { return value > 9; })</pre>
findIndex(): 数组实例的
findIndex
方法的用法与find
方法非常类似,返回第一个
符合条件的数组成员的位置 -
fill()实例方法 用给定值填充数组
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
-
entries(),keys() 和 values()实例方法 数组遍历 同 for...of 循环使用
keys()
是对键名的遍历values()
是对键值的遍历entries()
是对键值对的遍历for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"
-
includes()实例方法 判断数组是否包含某一数组元素
[1, 2, 3].includes(2) // true [1, 2, 3].includes(4) // false [1, 2, NaN].includes(NaN) // true
-
entries( )实例方法
entries()实例方式生成的是Iterator形式的数组,那这种形式的好处就是可以让我们在需要时用next()手动跳转到下一个值。我们来看下面的代码:
let arr=['hao','ha','hi'] let list=arr.entries(); console.log(list.next().value);//hao console.log(list.next().value);//ha console.log(list.next().value);//hi
11.对象的扩展
-
声明变量直接赋值
let name="jspang"; let skill= 'web'; var obj= {name,skill}; console.log(obj); //Object {name: "jspang", skill: "web"}
-
对象Key值构建
有时候我们会在后台取出key值,而不是我们前台定义好的,这时候我们如何构建我们的key值那。比如我们在后台取了一个key值,然后可以用[ ] 的形式,进行对象的构建
let key='skill'; var obj={ [key]:'web' } console.log(obj.skill);
-
Object.is( ) 对象比较
ES5 比较两个值是否相等,只有两个运算符:相等运算符(
==
)和严格相等运算符(===
)。它们都有缺点,前者会自动转换数据类型,后者的NaN
不等于自身Object.is
就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致var obj1 = {name:'feng'}; var obj2 = {name:'feng'}; console.log(obj1.name === obj2.name);//true console.log(Object.is(obj1.name,obj2.name)); //true console.log(+0 === -0); //true console.log(NaN === NaN ); //false console.log(Object.is(+0,-0)); //false console.log(Object.is(NaN,NaN)); //true
-
Object.assign() 对象的合并
Object.assign(参数1,参数2,参数3) 将源对象(source)的所有可枚举属性,复制到目标对象(target)
一个参数是目标对象,后面的参数都是源对象
const target = { a: 1 } const source1 = { b: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
注意:
- 浅拷贝 拷贝对象属性的址,而非值
const obj1 = {a: {b: 1}}; const obj2 = Object.assign({}, obj1); obj1.a.b = 2; obj2.a.b // 2
- 同名属性替换
const target = { a: { b: 'c', d: 'e' } } const source = { a: { b: 'hello' } } Object.assign(target, source) // { a: { b: 'hello' } }
- 数组处理
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
//相当于同名属性替换
``` - 浅拷贝 拷贝对象属性的址,而非值
-
Object.keys(),Object.values(),Object.entries()
Object.keys() 返回对象所有键的新数组
var obj = { foo: 'bar', baz: 42 }; Object.keys(obj) // ["foo", "baz"]
Object.values() 返回对象所有值的新数组
const obj = { 100: 'a', 2: 'b', 7: 'c' }; Object.values(obj) // ["b", "c", "a"]
Object.entries() 返回对象所有键值对的新数组
const obj = { foo: 'bar', baz: 42 }; Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
12.in的用法
in是用来判断对象或者数组中是否存在某个值的。我们先来看一下用in如何判断对象里是否有某个值
判断对象:
let obj={
a:'jspang',
b:'技术胖'
}
console.log('a' in obj); //true
判断数组:
ES5判断的弊端:以前会使用length属性进行判断,为0表示没有数组元素。但是这并不准确,或者说真实开发中有弊端
let arr=[,,,,,];
console.log(arr.length); //5 这是个坑
//es6
let arr=[,,,,,];
console.log(0 in arr); //false 空数组,判断0下标是否存在
let arr1=['jspang','技术胖'];
console.log(0 in arr1); // true
版权:本文为资源整理,侵权即删,欢迎转载。