ECMA基础

名称的含义:

  • ECMA是标准,JS是实现。

类似于HTML5是标准,IE10、Chrome、FF都是实现

  • ECMAScript简称ECMA或ES

ECMAScript ≈ JS

兼容性问题:

浏览器不兼容ES6:(ES2015)-IE10+、Chrome、FireFox、移动端、NodeJS

浏览器支持情况:Chrome 58、Edge14、Firefox 54、Safari10以及Opera55版本以及之后版本支持es5。

可以通过编译、转换达到兼容性使用的目的:

1.在线转换

2.提前编译

babel==browser.js

一.变量

ES5 只有全局作用域和函数作用域。会导致:

  1. 内层变量覆盖外层变量
var tmp = new Date();

   function f() {

  console.log(tmp); //undefined

   if (false) {

  var tmp = "hello world";

  }

  }
复制代码
  1. 变量泄露,成为全局变量
var s = 'hello';

   for (var i = 0; i \< s.length; i++) {

   console.log(s[i]);

   }

   console.log(i); // 5
复制代码

ES6 提供 let 和 const 来代替 var声明变量,新的声明方式支持用大括号表示的块级作用域,这会带来一些好处:

  1. 不再需要立即执行的函数表达式(IIFE)

  2. 循环体中的闭包不再有问题

  3. 防止重复声明变量

  • Var
  1. 可以重复声明

  2. 无法限制修改

  3. 没有块级作用域

  • Let
  1. 不能重复声明

  2. 变量-可以修改

  3. 块级作用域

  • Const
  1. 不能重复声明

  2. 常量-不能修改

  3. 块级作用域

默认使用let,只有当写保护的变量或者常量用const。

默认使用 const,只有当确实需要改变变量的值的时候才使用 let。

二. 函数

  • 箭头函数
function 名字(){

   }
复制代码
()=\>{

   }
复制代码
  1. 如果只有一个参数,()可以省略

  2. 如果只有一个return,{}可以省略

  3. =>不只是关键字function的简写,还与包围它的代码共享同一个this,有效的解决this的指向问题。

  4. 箭头函数,每次被执行都返回的是一个新的函数引用

  • 函数的参数
  1. 函数的扩展/数组展开

没有展开语法的时候,只能组合使用 push,splice,concat等方法,来将已有数组元素变成新数组的一部分。有了展开语法,构造新数组会变得更简单、更优雅。

延展操作符...可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开;还可以在构造对象时,将对象表达式按key-value的方式展开。

1). 参数扩展(延展操作符):

收集剩余的参数

function aaa(a,b,..args){}

Rest Parameter必须是参数的最后一个

展开数组

展开后的效果,跟直接把数组的内容写在这里一样

Let arr1 = [1,2,3];

Let arr2 = […arr1]
复制代码

应用场景

a. 在函数调用时使用延展操作符

function sum(x, y, z) {

   return x + y + z;

   }

   const numbers = [1, 2, 3];

  console.log(sum(...numbers));
复制代码

b.构造数组、数组拷贝和连接多个数组

  • 构造
const stuendts = ['Jine','Tom'];

const persons = ['Tony',... stuendts,'Aaron','Anna'];

conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]
复制代码
  • 拷贝
var arr = [1, 2, 3];

var arr2 = [...arr]; // 等同于 arr.slice()

arr2.push(4);

console.log(arr2)//[1, 2, 3, 4]
复制代码
  • 连接
var arr1 = [0, 1, 2];

var arr2 = [3, 4, 5];

var arr3 = [...arr1, ...arr2];
复制代码

c. 克隆对象与合并对象

var obj1 = { foo: 'bar', x: 42 };

var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };

// 克隆后的对象: { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };

// 合并后的对象: { foo: "baz", x: 42, y: 13 }
复制代码

和参数列表的展开类似, ... 在构造字数组时, 可以在任意位置多次使用。

展开语法和 Object.assign() 行为一致, 执行的都是浅拷贝(只遍历一层)。

在ECMAScript 2018中延展操作符增加了对对象的支持

d. 函数参数默认值

function(a,b=2,c=3){}

函数参数默认值不仅能是代码变得更加简洁而且能规避一些问题。比如:之前的默认写法var height = height || 100 ;当height为0或""时就会出问题

2). 解构赋值

通过解构赋值可以方便的交换两个变量的值。

  1. 左右两边结构必须一样(括号两边一一对应)

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

  1. 右边必须是个东西(json、数组…)

Let {a,b,c} = {a:4,b:5,c:6}

  1. 声明和赋值不能分开(即必须在一句话里完成)

三.数组

  • map 映射 一个对一个

传入方法 一个对一个的处理数组中的元素,返回新的数组

let array = [1,2,3,4,5,6,7]

let result = array.map(item=\>item\*3)

console.log(result);
[ 3, 6, 9, 12, 15, 18, 21 ]
复制代码
  • reduce 汇总 一堆出来一个,比如总数、平均数、总价、总和

传入方法包含三个参数(temp过程值,itme从1开始的元素,index下标),返回计算后的结果值

let array = [1, 2, 3, 4, 5, 6, 7]

let result = array.reduce(function(temp, item, index) {

return temp + item

})

 console.log(result)

28
复制代码
  • filter 过滤器

传入方法根据条件过滤返回新数组

let array = [1, 2, 3, 4, 5, 6, 7]

let result = array.filter(item =\> item % 3 === 0)

console.log(result)

 [ 3, 6 ]
复制代码
  • foreach 迭代

第一个参数是item,第二个是index,迭代数组

  • for..of

适合遍历数组。循环出来的是元素value值。如果实在想用for...of来遍历普通对象的属性的话,可以通过和Object.keys()搭配使用,先获取对象的所有key的数组然后遍历

  • for..in

for...in穷举对象的所有属性,包括自定义的添加的属性也能遍历到。适合遍历对象属性。循环出来的是key值。

  • Array.prototype.includes()

includes() 函数用来判断一个数组是否包含一个指定的值,如果包含则返回 tru否则返回false。

let arr = ['1', '2', '3'];

if (arr.includes('1'))

{

console.log('1存在');

 }
复制代码
  • Array.from()

将伪数组对象或可遍历对象转换为真数组

如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,称为伪数组。典型的伪数组有函数的arguments对象,以及大多数 DOM 元素集,还有字符串。

  • Array.of(data1, data2, data3)

将一系列值转换成数组。 Array.of( )方法总会创建一个包含所有传入参数的数组,而不管参数的数量与类型

当调用 new Array( )构造器时,根据传入参数的类型与数量的不同,实际上会导致一些不同的结果

let items = new Array(2) ;

 console.log(items.length) ; // 2

console.log(items[0]) ; // undefined

 console.log(items[1]) ;
复制代码

当使用单个数值参数来调用 Array 构造器时,数组的长度属性会被设置为该参数。

let items = new Array(1, 2) ;

 console.log(items.length) ; // 2

console.log(items[0]) ; // 1

console.log(items[1]) ; // 2
复制代码

如果使用多个参数(无论是否为数值类型)来调用,这些参数也会成为目标数组的项。

let items = Array.of(1, 2);

console.log(items.length); // 2

console.log(items[0]); // 1

console.log(items[1]); // 2

items = Array.of(2);

console.log(items.length); // 1

console.log(items[0]); // 2
复制代码
  • Array.every

每个值是否满足条件,如果是则返回true,如果不是则返回false

  • Array.some

是否有其中一个值满足条件,如果是则返回true,如果不是则返回false

  • Array.find()

数组实例的find方法,用于找出第一个符合条件的数组成员。如果没有符合条件的成员,则返回undefined。

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

  • Array.findIndex()

返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。

[1, 5, 10, 15].findIndex(function(value, index, arr) {

return value > 9;

}) // 2
复制代码

四.字符串

  • startsWith

以’XXX’开头,返回布尔值

  • endsWith

以’XXX’结尾,返回布尔值

  • 模板字符串

拼接字符串,不用单引号和双引号用反单引号包裹字符串,可以传参,可以换行。

参数传递时将变量放在大括号${}之中

let temp = '456'

let str = \`123\${temp}789\`

console.log(str)

//123456789
复制代码

五.面向对象

  • class

增加class关键字

构造器和类分开了

Class里面可以直接加方法

constructor构造函数,实例化的时候将会被调用,如果不指定,那么会有一个不带参数的默认构造函数

React的组件就是一个个class

之前是:

function User(user,age){

 this. user = user

this.age = age

}

User.prototype.showName=function(){

console.log(this.name)

}
复制代码

现在是:

class User{

constructor(name, age) {

this.name = name

this.age = age

}

showName(){

console.log(this.name)

}

}
复制代码
  • extends继承

子类必须要在constructor中指定super 函数,否则在新建实例的时候会报错

如果没有置顶consructor,默认带super函数的constructor将会被添加

class superUser extends User{

constructor(name, age,love) {

super(name,age)

this.love = love

}

showLove(){

}

}
复制代码

六.JSON

JSON.stringify

JSON的字符串化

JSON.parse

字符串转JSON

  • 简写
  1. 名字和值即key和value一样时可以只写一个

  2. 对象中也可以直接写变量,非常简洁

  3. Json中的function可以省略到只写方法名(:function都可以去掉)

  • JSON对象的标准写法:
  1. 只能用双引号

  2. 所有的名字都必须用引号包起来

七.JSON

是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。

要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set:

var s1 = new Set(); // 空Set

var s2 = new Set([1, 2, 3]); // 含1, 2, 3
复制代码

重复元素在Set中自动被过滤:

var s = new Set([1, 2, 3, 3, '3']);

s; // Set {1, 2, 3, "3"}
复制代码

注意数字3和字符串'3'是不同的元素。

通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果:

s.add(4);

s; // Set {1, 2, 3, 4}

s.add(4);

s; // 仍然是 Set {1, 2, 3, 4}
复制代码

通过delete(key)方法可以删除元素:

var s = new Set([1, 2, 3]);

s; // Set {1, 2, 3}

s.delete(3);

s; // Set {1, 2}
复制代码

八.Map

Map是一组键值对的结构,具有极快的查找速度。

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);

m.get('Michael'); // 95
复制代码

初始化Map需要一个二维数组,或者直接初始化一个空Map。Map具有以下方法:

var m = new Map(); // 空Map

m.set('Adam', 67); // 添加新的key-value

m.set('Bob', 59);

m.has('Adam'); // 是否存在key 'Adam': true

m.get('Adam'); // 67

m.delete('Adam'); // 删除key 'Adam'

m.get('Adam'); // undefined
复制代码

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:

var m = new Map();

m.set('Adam', 67);

m.set('Adam', 88);

m.get('Adam'); // 88
复制代码

九.Promise

含义:

  • 异步:操作之间无关联性,可以同时进行多个操作。代码复杂

  • 同步:同时只能做一件事。代码简单

ES6提供了一个原生的构造函数Promise。Promise的出现是为了解决JavaScript中异步编程的问题。传统的异步编程最大的特点就是地狱般的回调嵌套,一旦嵌套次数过多,就很容易使我们的代码难以理解和维护。 Promise则可以让我们通过链式调用的方法去解决回调嵌套的问题,使我们的代码更容易理解和维护。
Promise函数体的内部包裹着一个异步的请求或者操作或者函数;然后我们可以在这个异步的操作完成的时候使用resolve函数将我们获得的结果传递出去,或者使用reject函数将错误的消息传递出去。

Promise用来消除异步操作

用同步的方式写异步代码,接收一个函数参数,传入resolve,reject

参数resolve表示成功

参数reject表示失败

  • 因为Promise是一个构造函数,所以我们使用了new操作符来创建promise

  • 构造函数Promise的参数是一个函数(暂时叫它func),这个函数(func)有两个参数resolve和reject,它们分别是两个函数,这两个函数的作用就是将promise的状态从pending(等待)转换为resolved(已解决)或者从pending(等待)转换为rejected(已失败)。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。promise对象初始化状态为 pending ;当调用resolve(成功),会由pending => fulfilled;当调用reject(失败),会由pending => rejected。

  • 创建后的promise有一些方法,then和catch。当然我们也可以人为的在Promise函数上添加一些满足我们自己需求的方法,方便每一个promise对象使用

方法:

Promise对象可以通过使用then方法将上一步返回的结果获取过来(不管是resolved还是rejected),可以通过使用catch方法捕获Promise对象在使用catch之前的异常。

then方法可以接受两个函数作为参数,第一个函数是用来处理resolve的结果,第二个是可选的,用来处理reject的结果。也就是说,我们在创建p这个Promise对象的时候,通过函数resolve传递出去的结果可以被p的第一个then方法中的第一个函数捕获然后作为它的参数。通过函数reject传递出去的结果可以被p的第一个then方法中的第二个函数捕获然后作为它的参数。

一旦创建一个Promise对象之后,我们就可以使用then方法来进行链式的调用,而且我们可以把每一次的结果都返还给下一个then方法,然后在下一个then方法中对这个值进行处理。每一个then方法中都可以再次新创建一个Promise对象,然后返还给下一个then方法处理。

  • Promise.all

接收一个数组参数,里面的值最终都返回Promise对象。包装许多个Promise实例,然后组成了一个新的Promise对象。新的Promise对象的状态由前面几个被包裹的Promise对象的状态决定,如果前面的Promise都被resolve了,那么新的Promise的状态也是resolve的;只要有一个Promise被reject了,那么组成的新的Promise的状态也是reject的。数组中的异步操作并行执行,都执行完了才会进入到then里面。

Promise.all([\$.ajax(),\$.ajax()]).then(results=\>{

 //成功

}err=\>{

//失败

})
复制代码
  • Promise.reac

接收一个数组参数,里面的值最终都返回Promise对象。包装许多的Promise对象,然后组成了一个新的Promise对象,但是使用Promise.race的含义是:只要包裹的的Promise对象中有一个的状态发生了改变,那么组成的这个新的Promise对象的状态就是上面那个率先改变的Promise实例的状态。数组中的异步操作并行执行,第一个执行完了就会会进入到then里面。

  • Promise.resolve

将一个值转变为一个Promise对象,使它具有Promise的一些方法和特性。方法产生的Promise对象的状态是resolved的

  • Promise.reject

将一个值转变为一个Promise对象,使它具有Promise的一些方法和特性。方法产生的Promise对象的状态是rejected的

十.Async与await

async/await解决回调地狱问题,使异步代码看起来像同步操作。

应用场景:

  • 获取异步函数的返回值

异步函数本身会返回一个Promise,所以我们可以通过then来获取异步函数的返回值。

async function functionName(data1, data2) {

const d1=await count1(data1);

const d2=await count2(data2);

return d1+d2;

}

functionName
('person','children').then(console.log);//通过then获取异步函数的返回值。

function count1(data) {

return new Promise((resolve, reject) =\> {

setTimeout(() =\> {

resolve(data.length);

 }, 1000);

});

}
复制代码
  • async/await在并发场景中的应用

没有依赖关系的请求,通过Promise.all来实现await的并发调用。

async function charCountAdd(data1, data2) {

const [d1,d2]=await Promise.all([charCount(data1),charCount(data2)]);

return d1+d2;

}

charCountAdd('Hello','Hi').then(console.log);

function charCount(data) {

return new Promise((resolve, reject) =\> {

setTimeout(() =\> {

resolve(data.length);

}, 1000);

});

}
复制代码
  • async/await的几种错误处理方式
  1. 捕捉整个async/await函数的错误
async function charCountAdd(data1, data2) {

const d1=await charCount(data1);

const d2=await charCount(data2);

return d1+d2;

}
 charCountAdd('Hello','Hi')

.then(console.log)

.catch(console.log);//捕捉整个async/await函数的错误
复制代码
  1. 捕捉单个的await表达式的错误
async function charCountAdd(data1, data2) {

const d1=await charCount(data1)

.catch(e=\>console.log('d1 is null'));

const d2=await charCount(data2)

.catch(e=\>console.log('d2 is null'));

return d1+d2;

}

charCountAdd('Hello','Hi').then(console.log);
复制代码
  1. 同时捕捉多个的await表达式的错误
async function charCountAdd(data1, data2) {

let d1,d2;

try {

d1=await charCount(data1);

d2=await charCount(data2);

}catch (e){

console.log('d1 is null');

}

return d1+d2;

}

 charCountAdd('Hello','Hi')

.then(console.log);

function charCount(data) {

return new Promise((resolve, reject) =\> {

setTimeout(() =\> {

resolve(data.length);

}, 1000);

});

}
复制代码

十一.Object

  • Object.values()

Object.values()是一个与Object.keys()类似的新函数,但返回的是Object自身属性的所有值,不包括继承的值。

const obj = {a: 1, b: 2, c: 3};

const vals=Object.keys(obj).map(key=\>obj[key]); //es7

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

const values=Object.values(obj1); //es8

console.log(values);//[1, 2, 3]
复制代码
  • Object.entries

bject.entries()函数返回一个给定对象自身可枚举属性的键值对的数组。

Object.keys(obj).forEach(key=\>{ //es7

console.log('key:'+key+' value:'+obj[key]);

})

//key:a value:1

//key:b value:2

//key:c value:3

for(let [key,value] of Object.entries(obj1)){ //es8

console.log(\`key: \${key} value:\${value}\`)

}

//key:a value:1

//key:b value:2

//key:c value:3
复制代码

十二.模块化

模块的功能主要由 export 和 import组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export来规定模块对外暴露的接口,通过import来引用其它模块提供的接口。同时还为模块创造了命名空间,防止函数的命名冲突。

  • 导出(export)

ES6将一个文件视为一个模块。允许在一个模块中使用export来导出多个常量、变量或函数

export var name = 'abc'

export {name, age};

export function showName(name) {

return name;

}
复制代码
  • 导入(import)

通过import引用定义好模块的输出。一条import语句可以同时导入默认函数和其它变量。

import {myModule} from 'myModule';

import {name,age} from 'user';
复制代码
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值