es6 filter函数的用法_ES6语法重点整理

本文详细介绍了ES6中的核心特性,包括数组、函数、Symbol和对象的用法,重点讲解了filter函数的使用。此外,还探讨了Proxy和Reflect、Generator函数和Promise对象以及Class和Module。通过实例解析,帮助开发者更好地理解和应用ES6。
摘要由CSDN通过智能技术生成

目录:

  1. 数组、函数、Symbol和对象
  2. Proxy和Reflect
  3. Generator函数和Promise对象
  4. Class、Module

ES6简介:ECMAScript6是JavaScript语言的下一代标准,在2015年6月正式发布。其目标是使JavaScript语言可用于编写复杂的大型应用程序,成为企业级开发语言。

本文参考:《ES6 标准入门》阮一峰,《JavaScript权威指南》、JavaScript标准库

数组、函数、Symbol和对象

数组

1、数组在ES6与ES5用法的异同

let arrayLike = {
'0' : 'T',
'1' : 'h',
'2' : 'i',
'3' : 'n',
'4' : 'k',
length: 5
};

// ES5的写法
const array1 = [].slice.call(arrayLike);
// ES6的写法
const array2 = Array.from(arrayLike);
console.log(array1);
console.log(array2);

输出:

[ 'T', 'h', 'i', 'n', 'k' ]
[ 'T', 'h', 'i', 'n', 'k' ]

只要是部署了Iterator接口的数据结构,Array.from都能将其转为数组。

2、新语法

for(let index of array2.keys()){
console.log(index);
}
for(let [index,elem] of array2.entries()){
console.log(index + ' - ' + elem);
}

keys()跟entries()是ES6提供的新方法,用于遍历数组。

函数

1、默认值

es6之前,js不能直接为函数的参数指定默认值。es6赋给默认值的例子如下:

'use strict';
function billboard(author='Linkin Park', song = 'numb'){
console.log(author + ' --- ' + song);
}
billboard();
billboard('Taylor swift', 'shake it off');

通常默认值为函数的未参数。

2、rest参数

ES6引入了rest参数,用于获取函数的多余参数,这样就不需要使用arguments对象了。

function album(author, ...songs){
console.log('author: ' + author);
for(let song of songs){
console.log(song);
}
}
album('Eason', '放', '收心操', '海胆');

3、替换apply方法

扩展运算符(…)可以展开数组,所以不再需要apply方法将数组转为函数的参数。

function Mayday(a, b ,c ,d, e){
console.log(a + ', '+ b + ', '+ c + ', '+ d + ', '+ e + ', ')
}
const args = ['Monster', 'Ashin', 'Stone', 'Matthew Tsai', 'Lau Ming'];

// es5写法
Mayday.apply(null,args);

// es6写法
Mayday(...args);

4、箭头函数

ES6允许使用箭头定义函数。

let sum = (male, female) => {
console.log('新浪瘫痪');
};
sum('deer', 'Traey Miley’);

Symbol

1、概述

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。只要属性名是Symbol类型,可以保证不会与其他属性名产生冲突。

let Mayday = Symbol();
let SHE = Symbol();
let JayChou = Symbol('中国风');
let Beyond = Symbol('永远的beyond');

let JJ_Lin = Symbol.for('Singer');
let Leehom_Wang = Symbol.for('Singer');
console.log(JayChou === Beyond);  // false
console.log(Mayday === SHE);  // false
console.log(JJ_Lin === Leehom_Wang); // true

每一个symbol都不一样所以Mayday、SHE、JayChou、Beyond都是独一无二的。而用Symbol.for()可以做到使用同一个Symbol值,所以JJ_Lin和Leehom_Wang是一样的普通歌手。

2、消除魔法字符串

这个很像java中的Enum类型的用法。

const singerAttr = {
maestro: Symbol('change'),
only: Symbol('name'),
outstanding: Symbol(),
};
function getName(singer){
switch(singer){
case singerAttr.maestro:
console.log('Michael');
break;
case singerAttr.only:
console.log('JayChou');
break;
case singerAttr.outstanding:
console.log('JJ_Lin');
break;
}
}
getName(singerAttr.maestro);
getName(singerAttr.only);
getName(singerAttr.outstanding);

3、Symbol方法和内置的Symbol值

ES6可以定义自己使用的Symbol值,还提供了11个内置的Symbol值。

class Music {
[Symbol.sing](string){
return 'name : '+string;
}
}
const music = new Music();
console.log(music[Symbol.sing]('JJ_lin'));
console.log('a = ' + ‘JayChou'.search('a'));

Symbol.sing是自定的,search是内置的属性。

let obj = {
[Symbol.toPrimitive](singer){
switch(singer){
case 'number':
return 2;
case 'string':
return 'JayChou';
case 'default':
return 'JJ_Lin'
}
}
};
console.log(5 * obj);

重写对象的Symbol.toPrimitive属性。

补充

对象

对象是JavaScript的基本数据类型。对象是一中复合值:它将很多值聚合在一起,可以通过名字访问这些值。

1、创建对象最简单的方式就是使用对象直接量

const Maestor = {
name: 'Michael',
gender: 'male',
title: 'only',
dance() {
console.log('.......');
}
};
console.log(Maestor);  // { name: 'Michael', gender: 'male', dance: [Function: dance] }
console.log(Maestor.name); // Michael

Maestor.title = 'KingOfPop';
console.log(Maestor.title); // KingOfPop

也可用通过new的方式创建对象

let nowDays = new Date();

2、Object.assign()

Object.assign()方法用来将源对象的所有可枚举属性复制到目标对象。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。只要有一个参数不是对象,就会抛出TypeError错误。

Object.assign(Maestor, {
resurrection: 'resurrection'
}, {
sing() {
console.log('sing........')
}
});
console.log(Maestor.resurrection); // resurrection
Maestor.sing();  // sing........

3、Object.prototype属性

引用:Object.prototype属性表示Object的原型对象。JavaScript中几乎所有的对象都是Object的实例;所有的对象都继承了Object.prototype的属性和方法。它们可以被覆盖(除了以null为原型的对象,如 Object.create(null))。例如,新的构造函数的原型覆盖原来的构造函数的原型,提供它们自己的 toString() https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype)

Proxy和Reflect

1、Proxy

Proxy的意思是:代理。当访问添加了代理的对象时,都必须先经过代理才能访问到对象。

let actor = {
get: function(target, name){
if(name === 'prototype') return Object.prototype;
if(name === 'Miranda') return 'She is good(^.^)';
return 'who?'
},
apply: function(target, thisBinding, args) { console.log(args[0]); },
construct: function(target, args) {
return { name: args[1] };
}
};
let man = new Proxy(function(say, fire){
return '...';
}, actor);
man('Justin', 'Orlando');  // Justin
let another = new man('Justin', 'Orlando');
console.log(another.name); // Orlando
console.log(man.Miranda);  // She is good(^.^)

get(target, propKey, receiver):拦截对象的读取属性;
apply(target, object, args):拦截Proxy实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
construct(target, args, proxy):拦截Proxy实例作为构造函数调用的操作,比如new proxy(…args)。

总共有11个拦截方法(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy)。

2、Reflect

Reflect是一个内置的对象,它提供可拦截JavaScript操作的方法。方法与Proxy的方法相同。Reflect不是一个函数对象,因此它是不可构造的。

Reflect对象提供的静态函数,与Proxy提供的方法名称相同。这些方法中的一些与Object上的对应方法相同。具体参考https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect)。

Generator函数和Promise对象

Generator函数

Generator函数是ES6提供的一种异步编程解决方案。该函数有两个特征:1、function与函数名之间有一个星号;2、函数体内部使用yield语句定义不同的内部状态。

普通的Generator函数如下:

function *generatorDemo(){
yield 'z';
yield 'h';
yield 'a';
yield 'o';
}
let demo = generatorDemo();
console.log(demo.next());  // { value: 'z', done: false }
console.log(demo.next());  // { value: 'h', done: false }
console.log(demo.next());  // { value: 'a', done: false }
console.log(demo.next());  // { value: 'o', done: false }
console.log(demo.next());  // { value: undefined, done: true }

调用generatorDemo()后,该函数并不执行,而是返回一个指向内部状态的指针对象(遍历器对象)。想要往下执行必须调用next方法,使得指针指向下一个地方。当返回的状态done=true时表示遍历结束了。

next方法的作用是分阶段执行Generator函数。每次调用next方法,会返回一个对象,表示当前阶段的信息(value属性和done属性)。value属性是yield语句后表达式的值,表示当前阶段的值;done属性是一个布尔值,表示Generator函数是否执行完毕。

更近一步分析Generator函数:

function* tapNumber(first)
{
let second = 2 * ( yield (first+1));
let third = yield (second/3);
return ( first + second + third);
}
let tap = tapNumber(5);
console.log(tap.next()); // { value: 6, done: false }
console.log(tap.next()); // { value: NaN, done: false }
console.log(tap.next()); // { value: NaN, done: true }

我们理想得到的结果应该是:21。但是得到的结果是NaN。为什么呢?

原因:

1、yield语句只是一个暂停标志,当调用next()时Generator函数会从上次停止的地方开始执行。

2、因为并没有给next()传入参数,所以let second = 2 * undefined,second=undefined。

那我们怎么得到想要的结果呢?修改代码如下:

let tapTap = tapNumber(5);
let tapTapNext1 = tapTap.next();
console.log(tapTapNext1);  // { value: 6, done: false }
let tapTapNext2 = tapTap.next(tapTapNext1.value);
console.log(tapTapNext2);  // { value: 4, done: false }
console.log(tapTap.next(tapTapNext2.value)); // { value: 21, done: true }

把上一步得到的value传递给要执行的next(),这样我们就得到了想要的结果。yield本身并不返回任何值,它只是一个暂停状态。

Generator函数是协程在ES6中的实现,最大特点就是可以交出函数的执行权(即暂停执行)。整个Generator函数就是一个封装的异步任务。异步操作需要暂停的地方,都用yield语句注明。协程遇到yield命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。

Promise对象

Promise就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的API,可共进异步处理。

Promise有3种状态:Pending、Resolved和Rejected。只会从Pending到Resolved和Pending到Rejected,状态一旦改变就不会再变。

示例:

const IPromise = function(play){
return new Promise((resolve, reject)=>{
if(play === true){
resolve('I won't run away no more, I promise');
}else{
reject(new Error('oh on...'));
}
});
};
IPromise(false).then(lyrics=>{
console.log(lyrics);
}, errorMsg=>{
throw errorMsg;
}).catch(err => {
console.error('catch error', err);  // catch error Error: oh on...
});

当IPromise传入false时会抛出错误(throw errorMsg),所以能输出错误。

IPromise(true).then(lyrics=>{
console.log(lyrics); // I won't run away no more, I promise
}, errorMsg=>{
console.log(errorMsg);
}).then(lyrics => {
console.log('Even when I get bored, I promise'); // Even when I get bored, I promise
});

当IPromise传入true时会依次执行then。

Class、Module

Class

JS通常是通过定义一个函数来创建并初始化新对象。ES6语法引入了Class这个概念作为对象模板。如下:

class Singer {
constructor(){
if(new.target === Singer){
throw new Error('Singer不能实例化');
}
}
static hold(){
console.log('microphone');
}
feature(){
console.log('Hairstyle');
}
}
class Eason extends Singer {
constructor(){
// this.tall = '173cm'; // this只能在super之后使用
super();
this.gender='male';
}
}
const monIn = new Eason();
const theBestMoment = new Eason();
Eason.hold();
monIn.feature();
console.log(monIn.gender);
console.log(Eason === Eason.prototype.constructor);  // true
console.log(Eason.__proto__ === Singer); // true
console.log(Eason.prototype.__proto__ === Singer.prototype); // true

monIn.__proto__.printOwner = function(){
console.log('Eason');
};
monIn.printOwner(); // Eason
theBestMoment.printOwner(); // Eason


monIn.hold();  // TypeError: monIn.hold is not a function
const singer = new Singer(); // Error: Singer不能实例化

1、创建一个Singer类,并且Eason类继承Singer类。

2、因为Singer类中的constructor方法中有if(new.target === Singer),所以Singer类不能new。

3、static方法直接用类名(父类、子类都可以)调用,不能用实例调用。

4、Eason类中的constructor方法内this必须在super()之后使用,因为子类是继承的父类的this。

5、类的所有实例共享一个原型对象。

Module

模块是一个独立的JavaScript文件。模块文件可以包含一个类定义、一组相关的类、一个实用函数库或者是一些待执行的代码。

ES6模块的设计思想是尽量静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块都只能在运行时确定这些东西。

ES6模块例子:

module-demo.js
function getMaestro(){
return firstName+' '+ middleName + ' ' + lastName;
}
const firstName = 'Niels';
const middleName = 'Henrik';
const lastName = 'Abel';

export {
firstName,
middleName,
lastName,
getMaestro
}

module-use.js
import {firstName, middleName, lastName, getMaestro } from './module-demo';

CommonJS的例子:
commonjs-demo.js
function getMaestro(){
return firstName+' '+ middleName + ' ' + lastName;
}
const firstName = 'Niels';
const middleName = 'Henrik';
const lastName = 'Abel';

module.exports = {
firstName,
middleName,
lastName,
getMaestro
};

commonjs-use.js
const {firstName, middleName, lastName, getMaestro } = require('./commonjs-demo');
console.log(firstName);
console.log(getMaestro());

ES6模块加载的机制与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值