ECMAScript新特性--笔记

JavaScript语言本身指的就是ECMAScript。
ECMA官方网站 http://www.ecma-international.org/

1、nodemon 修改代码后,自动运行库

node 1.js
nodemon 1.js

2、块级作用域 let const

let 和const只针对作用域内的变量。闭包作用的一种延伸。先声明变量再使用变量。
const 声明常量和恒量。只读。声明的时候,必须赋值。不修改内存指向。例如

const name = 'zce';
name = 'jack'; // 会报错。修改了内存指向
const obj = {};
obj.name = 'ace';  //不报错。属性可以修改。

var声明变量,会对变量进行提升。提到代码的最前边。
最佳实践:不用var,主用const,配合let

3、数组的解构

const arr = [100,200,300];
//传统的写法
const foo = arr[0];
const bar = arr[1];
const bar2 = arr[2];
//数组解构的写法
const [ foo,bar,bar2 ] = arr;
//获取最后一个
const [ ,,bar2 ] = arr;
//提取当前位置后边的所有值,回返回一个数组(解构位置的最后使用)
const [foo,...rest] = arr;
console.log(rest);// [200, 300]

4、对象的解构

const obj = { name:'zce',age:18 };
const { name } = obj;
//解构的重命名
const name = 'tom';
const { name : objName = 'jack' } = obj;//重命名和给默认值
console.log(objName); // 解决命名冲突的问题.
//对console的解构
const { log }  = console;
log('foo');
log('foo1');
log('foo2');

5、模板字符串字面量 反单引号

${} 支持变量名,运算符,有返回值的js语句。

let name = 'zce';
let str =`my name is ${name},age ${10+8} ${Math.random()}`;
console.log(str);
//标签函数
const str = console.log`hello world`;

6、字符串的扩展方法

const  msg = 'Error: foo is not defined.';
// includes
msg.includes('foo'); // true
//startsWith
msg.startsWith('Error'); // true
//endsWith
msg.startsWith('.'); // true

7、参数默认值

//如果是是传多个形参,有默认值的形参放到最后
function foo(enable = true){
	console.log(enable)
}
foo();

8、剩余参数rest

//...args 只能使用一次,并且放在最后的位置
function foo(first,...args){
	console.log(args);
};
foo(1,2,3,4);

9、展开数组 spread

//打印每一项
const arr = ['foo','bar','baz'];
//最笨的方法
console.log(
	arr[0],
	arr[1],
	arr[2]
)
//ES5
console.log.apply(console,arr);
//ES6
console.log(...arr);

10、箭头函数

优点:代码更简短已读,不改变this的指向,当前作用域的this。

//原始写法
function inc (number){
	return number+1;
}
//ES6
const inc = (n,m)=>n+1;  //省略return,直接将结果作为返回值
console.log(inc(100))

//this指向
const person = {
	name:"tom",
	sayHiAsync:function(){
		const _this = this;
		setTimeout(function(){
			console.log(_this.name);
		},1000)
	},
	sayHiAsyncNew:function(){
		setTimeout(()=>{
			console.log(this.name);
		},1000)
	},	
}

11、对象字面量增强

const bar = '345';
const obj = {
	foo:123,
	//bar:bar,
	bar,
	method:function(){
		console.log("12345");
	},
	method1(){
		console.log("123456");
	}[1+1]:'123', //计算属性名
}

12、对象扩展方法

Object.assign:
将多个源对象中的属性复制到一个目标对象中
后边的对象覆盖到前边的对象

const soucre1 = {
	a:123,
	b:123,
}
const target = {
	a:456,
	c:456,
}
const res = Object.assign(target,source1);
console.log(target);// {a:123,c:456,b:123}
console.log(res === target); // true

Object.is
判断两个对象是否相当,用的比较少

Object.is(NaN,NaN);//true
Object.is(+0,-0);//false

13、Proxy 监视对象的改变

Object.defineProperty vue 3.0 以前使用,进行双向数据绑定
优势:defineProperty 只能监视属性的读写

  • proxy能够监视到更对对象操作, 例如。对象的删除,对象方法的调用。
  • 更好的支持数组对象的监视(重写数组的操作方法)
  • 以非侵入的方式监管了对象的读写
const person = {
	name:"ace",
	age:20
};
const personProxy = new Proxy(person,{
	get(target,property){
		return property in target ? target[property]:'default';
	},
	set(target,property,value){
		if( property === 'age'){
				if(!Number.isInteger(value)){
					throw new TypeError(`${value} is not an int `);
				}
		}
		target[property] = value;
	},
	deleteProperty(target,property){
		console.log('delete',property);
		delete target[property];
	}
});
console.log(personProxy.name);// zce
//设置
personProxy.age = "adfadad";//报错
personProxy.age = 100;

//执行删除的方法
delete personProxy.age;
console.log(person); // {name:"zce"}

汇总
在这里插入图片描述
如何使用proxy对数组进行监视?

const list = [];
const listProxy = new Proxy(list,{
	set(target,propertty,value){
		console.log('set',property,value);
		target[property] = value;
		return true;//表示设置成功
	}
})
listProxy.push(100);

14、Reflect 统一的对象操作API

  • 统一提供一套用于操作对象的API
  • Reflect属于一个静态类,不能通过new Reflect()方式去构造一个实例对象,只能去调用静态类中的方法,如Reflect.get()。
  • Reflect内部封装了一系列对对象的底层操作,提供了13个静态方法。
  • Reflect成员方法就是Proxy处理对象的默认实现。
const obj = {
	name:'zce',
	age:18
};
console.log( 'name' in obj );
console.log( delete obj['age'] );
console.log(Object.keys(obj));
//Reflect使用方法
console.log(Reflect.has(obj,'name'));
console.log(Reflect.deleteProperty(obj,'age'));
console.log(Reflect.ownKeys(obj));

在这里插入图片描述

15、class类

//ES5
function Person(name){
	this.name = name;
}
Person.prototype.say = function(){
	console.log(`hi,my name is ${this.name}`)
}
//ES6
class Person{
	constructor(name){
		this.name = name;
	}
	say (){
		console.log(`hi,my name is ${this.name}`)
	}
}

16、实例方法VS静态方法

静态方法,需要注意this指向,this不会指向某一个实例对象,指向当前的类

class Person{
	constructor(name){
		this.name = name;
	}
	say (){
		console.log(`hi,my name is ${this.name}`)
	}
	static create(name){
		console.log(this);
		return new Person(name);
	}
}
const tom =  Person.create('tom');
tom.say();

17、类的继承 extends

class Person{
	constructor(name){
		this.name = name;
	}
	say (){
		console.log(`hi,my name is ${this.name}`)
	}
}
//extends
class Student extends Person{
	constructor(name,number){
		super(name);//始终指向父类,调用就是调用父类的构造函数,继承父类的所有方法和属性
		this.number = number;
	}
	hello(){
		super.say();
		console.log(`my school number is  ${this.number}`)
	}
}
const s = new Student('jack','100');
s.hello();

18、Set数据结构

特定:Set中的元素只会出现一次,即 Set 中的元素是唯一的。

  • Set.prototype.size 返回 Set 对象中的值的个数
  • Set.prototype.add(value) 在Set对象尾部添加一个元素。返回该Set对象。
  • Set.prototype.clear() 移除Set对象内的所有元素。
  • Set.prototype.delete(value)
    移除Set中与这个值相等的元素,返回Set.prototype.has(value)在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。Set.prototype.has(value)在此后会返回false。
  • Set.prototype.entries()
    返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value,
    value]数组。为了使这个方法和Map对象保持相似, 每个值的键和值相等。
  • Set.prototype.forEach(callbackFn[, thisArg])
    按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了thisArg参数,回调中的this会是这个参数。
  • Set.prototype.has(value) 返回一个布尔值,表示该值在Set中存在与否。
  • Set.prototype.keys()
    与values()方法相同,返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
  • Set.prototype.values() 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值
  • Set.prototype@@iterator 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
const s = new Set();
s.add(1).add(2).add(3)
console.log(s);
s.forEach(i=>console.log(i));
for(let i of s){
	console.log(i)
}
//利用set进行数组去重
const arr = [1,2,3,4,1,3];
const res = new Set(arr);//利用set的特性去重
console.log(res);
//set 转换为数字
Array.from(new Set(arr));
[...new Set(arr)]

19、Map数据结构

const m = new Map();
const tom = {"name":"tom"};
m.set(tom,90);
console.log(m);
console.log(m.get(tom));
// m.has()
//m.delete();
// m.clear()

20、Symbol 数据类型

独一无二,实现方法内的私有方法
最主要的作用就是为对象添加独一无二的属性名

//Symbol数据类型
console.log(Symbol() === Symbol()); //false
//静态方法 for。 如果传的值不是字符串,会强制转成字符串
const s1 = Symbol.for('foo');
const s2 = Symbol.for('foo');
console.log(s1 === s2);//true
//获取属性名的区别
const obj = {
	[Symobol()]:’symbol value',
	"foo":"normal value"
};
for( var key in obj){
	console.log(key);
}
// 结果:foo; 只能获取到字符串类型的key
console.log(Object.keys(obj)); // 结果: ["foo"]
console.log(JSON.stringify(obj));// {"foo":"normal value"}

console.log(Object.getOwnPropertySymbols(obj));// 才能获取 Symbol() 类型的key

JS的7种数据类型
Number,boolean , Object , Symbol , String, Null, Undefined

21、for …of 循环

做完遍历所有数据结构的统一方式
可以使用break终止循环

const arr = [100,200,300,400,500];
for( const item of arr ){
	console.log(item);
	if(item > 100){
		break;
	} 
}

22、迭代器 Iterable接口

for…of 内部实现原理

const set = new Set(["foo","bar","baz"]);
const iterator = set[Symbol.iterator]();
console.log(iterator.next());// {value:"foo",done:false}
console.log(iterator.next());//{value:"bar",done:false}
console.log(iterator.next());//{value:"baz",done:false}
console.log(iterator.next());//{value:undefined,done:true}
console.log(iterator.next());//{value:undefined,done:true}

//实现可迭代接口
const obj = {
	[Symbol.iterator]:function(){
		return {
			next:function(){
				return { 
					value:"zce",
					done:true  //迭代有没有结束
				}
			}
		}
	}
}

//迭代器内部实现
const obj = {
	store:["foo","bar","baz"],
	[Symbol.iterator]:function(){
		let index = 0 ;
		const self = this;
		return {
			next:function(){
				const res = {
					value:self.store[index],
					done:index >= self.store.length
				}
				index++;
				return res;
			}
		}
	}
}
for ( const item of obj ){
	console.log(item);
}

23、迭代器设计模式

对外提供统一的遍历接口

// 迭代器设计模式
// 场景: 你我协同开发一个任务清单应用
//我的代码
const todos = {
	life:['吃饭','睡觉''打豆豆'],	
	learn:['语文','数学''英语'],
	work:['喝茶','code'],
	each:function(cb){
		const all = [].concat(this.life,this.learn,this.work);
		for( const item of all ){
			cb(item);
		} 
	},
	[Symbol.iterator]:function(){
		const all = [...this.life,...this.learn,...this.work];
		let index = 0 ;
		return {
			next:function(){
				const res = {
					value:self.store[index],
					done:index >= self.store.length
				}
				index++;
				return res;
			}
		}
	}
};
//你的代码
for( const item of todos ){
	console.log(item);
} 

24、生成器 Generator

避免异步编程中回调嵌套过深
踹一下,走一步

//应用
// 案例1:发号器
function * createIdMaker(){
	let id = 1;
	while(true){
		yield id++;
	}
}
const idMaker = createIdMaker();
console.log(idMaker.next().value);
console.log(idMaker.next().value);
console.log(idMaker.next().value);
console.log(idMaker.next().value);
//案例2:使用Generator 函数实现,iterator方法
const todos = {
	life:['吃饭','睡觉''打豆豆'],	
	learn:['语文','数学''英语'],
	work:['喝茶','code'],
	[Symbol.iterator]:function(){
		const all = [...this.life,...this.learn,...this.work];
		let index = 0 ;
		for(const item of all){
			yield item
		}
	}
};

for( const item of todos ){
	console.log(item)
}

25、 ECMAScript 2016

//Array 添加includes方法
const arr = ['foo',1,NaN,false];
console.log(arr.includes("foo"));// true ,相比于indexOf可以验证NaN是否存在
console.log(arr.includes(NaN));
//指数运算符
console.log(Math.pow(2,10));//借助于Math函数
console.log(2**10);//新的指数运算符

26、 ECMAScript 2017

对Object的三个扩展方法

const obj = {
	foo:'val1',
	bar:'val2'
};
//Object.values 类似于 Object.keys keys返回的是key,values返回的是value
console.log(Object.valuse(obj));// ['val1','val2']
//Object.entries 返回一个 key,val的数组
console.log(Object.entries(obj)); // [ ['foo','val1'],['bar','val2'] ]
for( const [ key,val] of Object.entries(obj) ){
	console.log(key,val);
}
//Object.getOwnPropertyDescriptors 获取对象中完整的描述信息
const p1 = {
	firstName:'Lei',
	lastName:'Wang',
	get fullName (){
		return this.firstName + ' ' +this.lastName;
	}
}
console.log(p1.fullName);// Lei Wang
//Object.assign 在复制时,把fullName当成了一个普通的属性,复制过来
const p2 = Object.assign({},p1);
p2.firstName = 'zce';
console.log(p2);// [firstName:'Lei',lastName:'Wang', fullName:'Lei Wang' ]

const desriptors = Object.getOwnPropertyDescriptors(p1);
console.log(desriptors);//获取详情
const p3 = Object.defineProperties({},desriptors);
p3.firstName = 'zce';
console.log(p3.fullName); // zce wang

//String.prototype.padStart / String.prototype.padEnd 
//字符串填充方法
const books = {
	html:5,
	css:123,
	javascript:1290
}
for( const [ name,count ] of Object.entries(books)){
	console.log(`${name.padEnd(16,'-')}|${count.toString().padStart(4,'0')}`);
}
//在函数中添加尾逗号
function foo(bar,baz,){}
const arr = [1,23,4,]
//Async/Await
//promise的语法糖,使代码,整体看起来更加整洁,易读
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值