ES6学习之二
本文的学习来自技术胖大神的教程:https://jspang.com/
1扩展运算符和rest运算符
扩展运算符和rest运算符,它们都是…(三个点)。
它们有很多相似之处,甚至很多时候不用特意去区分。
它们可以很好的解决参数和对象数组未知情况下的编程,让代码更健壮和简洁。
1.1对象扩展运算符(…)
当编写一个方法时,允许它传入的参数是不确定的。这时候可以使用对象扩展运算符来作参数。
例:
function test(...arg){
console.log(arg[0]);
console.log(arg[1]);
console.log(arg[2]);
console.log(arg[3]);
}
test(1,2,3);
说明可以传入多个值,并且就算方法中引用多了也不会报错。
1.2扩展运算符的用处
例1:声明两个数组arr1和arr2,然后把arr1赋值给arr2,然后改变arr2的值:
let arr1=['a','b','c'];
let arr2=arr1;
console.log(arr2);
arr2.push('d');
console.log(arr1);
可以看到arr1的值也改变了,因为这是对内存堆栈的引用,而不是真正的赋值。
利用对象扩展运算符简单的解决这个问题:
let arr1=['a','b','c'];
let arr2=[...arr1];
console.log("arr2:",arr2);
arr2.push('d');
console.log("arr1:",arr1);
console.log("arr2:",arr2);
可以看到arr1并没有改变。
1.3 rest运算符
例:
function test(first,...arg){
console.log(arg.length);
}
test(1,2,3,4,5,6);
第一个参数1传给了first,剩下的参数传给了arg数组,所以arg长度为5
1.4循环输出rest运算符
可以用for…of循环,for…of的循环可以避免开拓内存空间,增加代码运行效率:
function test(first,...arg){
for(let val of arg){
console.log(val);
}
}
test(1,2,3,4,5,6);
2 ES6新增的数字操作
2.1二进制声明(不是ES6特性)
二进制的英文单词是Binary,二进制的开始是0(零),然后第二个位置是b(大小写都可以实现),然后跟上二进制的值就可以了。
2.2八进制声明(不是ES6特性)
八进制的英文单词是Octal,也是以0(零)开始的,然后第二个位置是O,然后跟上八进制的值就可以了。
例:
//二进制声明
let binary=0B010101;
console.log('二进制binary:',binary); //八进制声明
let octal=0O777;
console.log('八进制octal:',octal);
2.3数字验证
可以用Number.isFinite( )进行数字验证,只要是数字,不论是浮点型还是整形都会返回true,其他时候会返回false
console.log(Number.isFinite(888));
console.log(Number.isFinite(11/4));
console.log(Number.isFinite('abc'));
console.log(Number.isFinite(NaN));
console.log(Number.isFinite(undefined));
2.4 NaN验证
NaN是特殊的非数字,可以使用Number.isNaN()来进行验证
console.log(Number.isNaN(0));
console.log(Number.isNaN(NaN));
2.5判断是否为整数
Number.isInteger()
console.log(Number.isInteger(100));
console.log(Number.isInteger(99.99));
2.6转换
整数转换Number.parseInt()
浮点型转换Number.parseFloat()
let a='9.99';
let b='aaa';
console.log(Number.parseInt(a));
console.log(Number.parseFloat(a));
console.log(Number.parseInt(b));
console.log(Number.parseFloat(b));
2.7整数取值范围
整数的操作是有一个取值范围的,就是-(253-1)到253-1。
在计算时会经常超出这个值,所以要进行判断,ES6提供了两个常数,就不用去计算了,直接用就可以:
//最大安全整数
console.log(Number.MAX_SAFE_INTEGER);
//最小安全整数
console.log(Number.MIN_SAFE_INTEGER);
安全整数判断:
let c=Math.pow(2,53);
let d=Math.pow(2,53)-1;
console.log(Number.isSafeInteger(c));
console.log(Number.isSafeInteger(d));
3新增的数组知识
3.1 JSON数组格式转换:Array.from()方法
JSON的数组格式就是为了前端快速的把JSON转换成数组的一种格式
例:
let json={
0:1,
1:2,
2:'abc',
length:3
}
这就是一个标准的JSON数组格式(注意key值就是0,1,2...,不能随意起别的键名),跟普通的JSON对比是在最后多了一个length属性,没有length就只是字符串,有length才是数组。
这种特殊的json格式可以使用ES6的语法转变成数组:
let json={
0:1,
1:2,
2:'abc',
length:3
}
let arr=Array.from(json);
console.log(arr);
3.2 Array.of()方法
可以把一堆文本或者变量转换成数组。(之前可以用eval来进行转换,但是eval的效率很低,会拖慢程序,所以尽量不要用)
例:
let arr=Array.of(1,2,3,4);
console.log(arr); let arr2=Array.of('a','b','c');
console.log(arr2);
3.3 find()方法
find()是一个实例方法,实例方法就是必须有一个已经存在的数组来调用,而前面两个方法是用Array对象直接调用的。
(java中曾学过静态方法和实例方法,所以这里很好理解)
find方法是从数组中查找,需要传入一个匿名函数,函数需要传入三个参数:
value:表示当前查找的值。
index:表示当前查找的数组索引。
arr:表示当前数组。
在函数中如果找到符合条件的数组元素就进行return,并停止查找。如果没有满足条件的,就返回undefinded。
例1:
let arr=[1,2,3,4,5];
console.log(arr.find(function(val,index,arr){
return val>3;
}));
例2:
let arr1=['a','b','c'];
console.log(arr1.find(function(val,index,arr){
return val=='d';
}));
3.4 fill()方法
fill()也是一个实例方法,它的作用是把数组进行填充,它接收三个参数,第一个参数是填充的变量,第二个是开始填充的位置,第三个是填充到的位置。
例:
let arr=[1,2,3,4,5];
arr.fill('abc',2,4);
console.log(arr);
3.5数组的遍历
1) for…of循环
这种形式比ES5的for循环要简单而且高效,比普通for少声明一个i,这个i用完就没意义了。
(for of就类似java中的增强for)
例:
let arr=[1,2,3,4,5];
for(let item of arr){
console.log(item);
}
输出数组索引:
let arr=[1,2,3,4,5];
for(let index of arr.keys()){
console.log(index);
}
同时输出数组的内容和索引:
let arr2=['你好','abc','12345'];
for(let [index,item] of arr2.entries()){
console.log(index+':'+item);
}
2)forEach
forEach循环会自动省略为空的数组元素,相当于直接筛空了。
let arr=['abc','123','Hello'];
arr.forEach((val,index)=>console.log(index,val));
(这里用了箭头函数,先用一下,后面会再详细写)
3)filter
let arr=['abc','123','Hello'];
arr.filter(x=>console.log(x));
4)some
let arr=['abc','123','Hello'];
arr.some(x=>console.log(x));
5)map
map起到一个替换的作用:
let arr=['abc','123','Hello'];
console.log(arr.map(x=>'替换后的值'));
3.6数组转换字符串
1)join()方法
join()方法就是在数组元素中间,加了一些间隔,开发中很有用处。
let arr=['abc','123','Hello','你好'];
console.log(arr.join('-'));
2)toString()方法
转换时只是用逗号隔开了:
let arr=['abc','123','Hello','你好'];
console.log(arr.toString());
3.7 entries()方法
entries()生成的是Iterator形式的数组,这种形式的好处是可以在需要时用next()手动跳转到下一个值。Entries的意思是条目。
例:
let arr=['abc','你好','学习es6'];
let list=arr.entries();
console.log(list);
console.log(list.next().value);
当想生成一些不规则的循环时,就可以用entries,这就叫手动循环。(上面的for of循环叫自动循环)
例:
let arr=['abc','你好','学习es6'];
let list=arr.entries();
console.log(list.next().value);
console.log('---------------');
console.log(list.next().value);
console.log('***************');
console.log(list.next().value);
console.log('@@@@@@@@@@@@@@@');
console.log(list.next().value);
3.8 in的用法
in是用来判断对象或者数组中是否存在某个值的。
例:对象判断
let obj={
a:'你好',
b:'你是谁'
}
console.log('a' in obj);
console.log('你好' in obj);
说明判断的是key值
例:数组判断:
以前会使用length属性进行判断,其存在弊端:
let arr=[,,,];
console.log(arr.length);
数组中其实全是空值,却输出了长度为3,这是不准确的。
用ES6的in就可以解决这个问题:
let arr=[,,,];
console.log(0 in arr); let arr2=[1,2,3,];
console.log(0 in arr2);
注意:这里的0指的是数组下标位置是否为空。
4新增的函数知识
4.1参数的默认值
function fun1(a,b=1){
return a+b;
}
console.log(fun1(2));
4.2主动抛出错误
function fun2(a){
if(a==1){
throw new Error("这里报错了!");
}
return a+b;
}
console.log(fun2(1));
4.3严谨模式
之前严谨模式必须写在代码最上边,相当于全局使用,在ES6中可以写在函数体中,相当于针对函数来使用。
例:
function fun3(a,b=2){
'use strict'
return a+b;
}
console.log(fun3(1));
说明使用了默认值,再使用严谨模式的话,就会有冲突。
把默认值去掉:
function fun3(a,b){
'use strict'
return a+b;
}
console.log(fun3(1,2));
4.4获得需要传递的参数个数
function fun4(a,b){
return a+b;
}
console.log(fun4.length);
如果加上默认值:
function fun4(a,b=1){
return a+b;
}
console.log(fun4.length);
这说明length表示必须传入的参数个数。
4.5对象的函数解构
实际作用:后端经常返回来JSON格式的数据,直接把这个JSON格式数据当作参数,传递到函数内部进行处理。
例:
let json={
a:'abc',
b:'123'
}
function fun({a,b}){
console.log(a,b);
}
fun(json);
这样方便了很多,不用一个个传递参数了。
4.6数组的函数解构
let arr=['abc','123','哈哈'];
function test(a,b,c){
console.log(a,b,c);
}
test(...arr);
4.7最后的参数可以带逗号
之前是不能有,有了报错,现在没关系了
function show(a,b,c,){
console.log(a,b,c);
}
show(1,2,3,);
这个在实际开发中会带来方便。
4.8箭头函数
箭头函数使用频率非常高,所以单独总结了:
https://www.cnblogs.com/hzhjxx/p/12046043.html
5 ES6中对象
5.1对象赋值
原来怎么赋值的:
let name='小笼包';
let age=18; let obj={
name:name,
age:age
}
console.log(obj);
ES6允许把声明的变量直接赋值给对象。不用写key值了,直接把变量放进去,这样就大大简化了:
let name='小笼包';
let age=18; let obj={name,age}
console.log(obj);
5.2对象Key值构建
有时候前台不知道key值的名称,是要从后台取的,这时可以用[ ] 的形式,进行对象的构建:
let key='name';
let obj={
[key]:'前台定义的值'
}
console.log(obj);
5.3 is()方法
把两个对象进行比较。
之前可以用===来比较:
let obj1={name:'名字'};
let obj2={name:'名字'};
console.log(obj1.name===obj2.name);
现在可以用is方法:
let obj1={name:'名字'};
let obj2={name:'名字'};
console.log(Object.is(obj1.name,obj2.name));
这两种比较的区别:
===为同值相等,is()为严格相等
console.log(+0===-0);
console.log(Object.is(+0,-0));
console.log(NaN===NaN);
console.log(Object.is(NaN,NaN));
5.4 assign()合并对象
let a={
name:'名字'
}
let b={
age:20
}
let c={
like:'web'
}
let d=Object.assign(a,b,c);
console.log(d);
如果有重复的key值,后面的会覆盖前面的:
let a={
name:'名字'
}
let b={
age:20,
name:'名字2'
}
let c={
like:'web',
age:22,
}
let d=Object.assign(a,b,c);
console.log(d);
6 Symbol在对象中的应用
6.1用Symbol构建对象的Key
let sy=Symbol();
let obj={
[sy]:'sy的值'
}
console.log(obj[sy]);
obj[sy]='新值';
console.log(obj[sy]);
6.2 Symbol对象元素的保护作用
在对象中有很多值,但是循环输出时,并不希望全部输出,就可以使用Symbol进行保护
let obj={
name:'名字',
like:'吃'
}
let age=Symbol();
obj[age]=18;
console.log(obj);
for(let item in obj){
console.log(obj[item]);
}
可以看到,age被保护了。
7 Set和WeakSet数据结构
Set的定义和一些常用方法可以看这里:https://www.cnblogs.com/hzhjxx/p/11460420.html
7.1set的遍历
1)用for...of
let setArr=new Set(['abc','Hello','123']);
for(let item of setArr){
console.log(item);
}
2)forEach:
let setArr=new Set(['abc','Hello','123']);
setArr.forEach((val)=>console.log(val));
7.2 WeakSet
注意不能直接在new 的时候放入值,会报错,要先把对象定义好,再用add方法添进去。
let weakObj=new WeakSet();
let obj={
name:'大美女',
age:'18'
}
weakObj.add(obj);
console.log(weakObj);
WeakSet里边的值不允许有重复的对象:
let weakObj=new WeakSet();
let obj={
name:'大美女',
age:'18'
}
let obj2={
name:'大美女',
age:'18'
}
weakObj.add(obj);
weakObj.add(obj2);
console.log(weakObj);
因为obj和obj2不是同一个对象。
如果是同一个:
let weakObj=new WeakSet();
let obj={
name:'大美女',
age:'18'
}
let obj2=obj;
weakObj.add(obj);
weakObj.add(obj2);
console.log(weakObj);
8 Map数据结构
先看一个json对象的取值:
let json={
name:'大美女',
age:18
}
console.log(json.name);
这种方法其实是需要遍历整个对象进行寻找的,所以效率要比数组低。
8.1声明Map
let map=new Map();
用set方法添加值:
let json={
name:'大美女',
age:18
}
let map=new Map();
map.set(json,'me');
console.log(map);
map的灵活性就在此,key值和value值可以没规律,可以是任意类型。
8.2方法和属性
let json={
name:'大美女',
age:18
}
let map=new Map(); //添加值
map.set(json,'me');
map.set('me2',json); //长度
console.log(map.size); //取值
console.log(map.get(json));
console.log(map.get('me2')); //查找
console.log(map.has(json)); //删除
map.delete(json);
console.log(map); //清空
map.clear();
console.log(map);
Map应用广泛,因为他更灵活,更高效。
9用Proxy进行预处理
当操作一个对象或者方法时会有几种动作,例如在运行函数前初始化一些数据,在改变对象值后做一些善后处理。这些都算钩子函数。
Proxy的存在就可以给函数加上这样的钩子函数,可以理解为在执行方法前预处理一些代码。也可以简单的理解为是函数或者对象的生命周期。
Proxy的应用可以使函数更加强大,业务逻辑更加清楚,而且在编写自己的框架或者通用组件时非常好用。
9.1声明Proxy
new Proxy({},{});
第一个花括号相当于方法的主体,后边的花括号就是Proxy代理处理区域,相当于写钩子函数的地方。
9.2 get属性
get属性是在得到某对象属性值时预处理的方法,它接收三个参数:
target:得到的目标值
key:目标的key值,相当于对象的属性
property:这个不太常用
9.3 set属性
set属性是要改变Proxy属性值时,进行的预先处理。它接收四个参数:
target:目标值。
key:目标的Key值。
value:要改变的值。
receiver:改变前的原始值。
例:
let pro=new Proxy({
add:function(val){
return val+10;
},
name:'这是我的名字'
},{
get:function(target,key,property){
console.log('运行get');
return target[key];
},
set:function(target,key,value,receiver){
console.log('运行set');
return target[key]=value;
}
});
console.log(pro.name);
pro.name='新名字';
console.log(pro.name);
9.4 apply
apply是对方法的预处理
let target = function () {
return 'Hello';
};
var handler = {
apply(target, ctx, args) {
console.log('apply运行了');
return Reflect.apply(...arguments);
}
}
var pro = new Proxy(target, handler);
console.log(pro());
10 promise对象的使用
promise很好的解决了回调地狱的问题。
ES5的时候,在多层嵌套回调时,代码层次过多,很难进行维护和二次开发。
promise可以完美解决这个问题。
promise这个单词是“承诺”,当它成功时执行一些代码,当它失败时执行一些代码。它更符合人类的行为思考习惯。
promise执行多步操作非常好用。模仿一个多步操作的过程:
let state=1;
function step1(resolve,reject){
console.log('第一步:做饭');
if(state==1){
resolve('做饭完成');
}else{
reject('做饭失败');
}
}
function step2(resolve,reject){
console.log('第二步:吃饭');
if(state==1){
resolve('吃饭完成');
}else{
reject('吃饭失败');
}
}
function step3(resolve,reject){
console.log('第三步:洗碗');
if(state==1){
resolve('洗碗完成');
}else{
reject('洗碗失败');
}
} new Promise(step1).
then(function(val){
console.log(val);
return new Promise(step2);
}).
then(function(val){
console.log(val);
return new Promise(step3);
}).
then(function(val){
console.log(val);
return val
});
如果某一步出错:
promise可以让代码更加的结构化。在现在的开发中使用率算是最高的。
11 class类的使用
11.1类的声明
class Coder{
name(val){
console.log(val);
}
}
let me=new Coder;
me.name('你的名字');
当有多个方法时:
class Coder{
name(val){
return val;
}
skill(val){
console.log(this.name('张三')+'的技能是'+val);
}
}
let me=new Coder;
me.skill('web开发');
注意方法和方法中间不要写逗号,this指类本身。
11.2类的传参
用constructor( )进行传参。传递参数后可以直接使用this.xxx进行调用。
class Coder{
constructor(a,b){
this.a=a;
this.b=b;
}
add(){
return this.a+this.b;
}
}
let me=new Coder(1,2);
console.log(me.add());
11.3 class的继承
class Coder{
name(val){
console.log(val);
}
}
class Htmler extends Coder{ }
let me=new Htmler;
me.name('我是一个切图人员');
注意在写类的时候和ES5中的对象和构造函数要区分开,不要学混了。
12模块化操作
模块化操作主要包括两个方面:
export:模块的输出。
import:模块的引入。
谷歌浏览器地址栏中输入:
chrome://flags/,然后搜索javascript,把Experimental JavaScript设为启用:
引入js文件时,要加上type="module"
这样就可以直接预览效果了。
12.1 export的用法
export可以把变量,函数,对象进行模块化,提供外部调用接口,让外部进行引用。
12.1.1把一个变量模块化
temp.js:
export var a='abc';
index.js:
import {a} from './temp.js';
console.log(a);
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="module" src="index.js"></script>
</body>
</html>
12.1.2多变量的输出
temp.js:
var a='aaa';
var b='bbb';
var c='ccc'; export {a,b,c}
index.js:
import {a,b,c} from './temp.js';
console.log(a,b,c);
12.1.3函数的模块化输出
temp.js:
export function test(a,b){
return a+b;
}
index.js:
import {test} from './temp.js';
console.log(test(10,20));
12.1.4 as的用法
有时候不想暴露模块里的变量名称,而给模块起一个更语义化的名称,可以使用as来操作。
temp.js:
var a='张三';
var b=18;
export {
a as name,
b as age
}
index.js:
import {name,age} from './temp.js';
console.log(name,age);
12.2 export和export default的区别
加上default相当于是一个默认的入口。在一个文件里export default只能有一个。
例1:写两个export:
temp.js:
export var a ='aaa';
export function add(a,b){
return a+b;
}
index.js:
import {a,add} from './temp.js';
console.log(a,add(10,20));
例2:export default
export default var a=12345';
import str from './temp';
这时import可以不写{},而且可以自定义命名。
(这里在chrome预览时报错,以后还是找个方式打包一下,等学完webpack再修改这里。)
总结
开发时尽量使用ES6语法,多用才熟练。如果生产环境不兼容,可以写完再用babel等工具转换。
ES6学习之二的更多相关文章
- ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
- ES6学习(二)基础命令
一.Let 和 const 作用域的概念:在es5之前是有两个作用域,一个是全局作用域,另外一个是函数作用域,在es6中就多了这样一个块作用域.在这里let 和 const 就是传说中的块作用域,它 ...
- ES6学习笔记二
字符串遍历 var str = 'hello'; for(let s of str){console.log(s += ' ')} //h e l l o 字符串查找:添加了include(str,i ...
- ES6学习总结二(数组的四个方法,字符串)
数组 1 map 映射 一个对一个 如:分数数组[34,56,78,99]映射为[不及格,不及格,及格,及格]; 等级数组[23,56,89]映射为 [ {name:'lmx',level:1,rol ...
- ES6学习笔记二:各种扩展
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7242967.html 一:字符串扩展 1:字符串遍历器 for (let char of str) { // ...
- ES6学习笔记(二)——字符串扩展
相信很多人也和我一样,不喜欢这样循规蹈矩的逐条去学习语法,很枯燥乏味.主要是这样学完一遍之后,没过一段时间就忘到九霄云外了.不如实际用到的时候研究它记得牢靠,所以我就整理成笔记,加深记忆的同时便于复习 ...
- ES6学习笔记(二)
Set 和 Map 数据结构 1.set 基本用法 ES6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值 Set本身是一个构造函数,用来生成Set数据结构 const s ...
- es6学习笔记二:生成器 Generators
今天这篇文章让我感到非常的兴奋,接下来我们将一起领略ES6中最具魔力的特性. 为什么说是“最具魔力的”?对于初学者来说,此特性与JS之前已有的特性截然不同,可能会觉得有点晦涩难懂.但是,从某种意义上来 ...
- ES6学习(二):函数的扩展
chapter07 函数的扩展 7.1 函数默认值 7.1.1 参数默认值简介 传统做法的弊端(||):如果传入的参数相等于(==)false的话,仍会被设为默认值,需要多加入一个if判断,比较麻烦. ...
随机推荐
- java 根据秘钥,对数据进行加解密
package test; import com.alibaba.fastjson.JSONObject; import sun.misc.BASE64Decoder; import sun.misc ...
- pytorch源码解析:Python层 pytorchmodule源码
尝试使用了pytorch,相比其他深度学习框架,pytorch显得简洁易懂.花时间读了部分源码,主要结合简单例子带着问题阅读,不涉及源码中C拓展库的实现. 一个简单例子 实现单层softmax二分类, ...
- oracle函数 INITCAP(c1)
[功能]返回字符串并将字符串的第一个字母变为大写,其它字母小写; [参数]c1字符型表达式 [返回]字符型 [示例] SQL> select initcap('smith abc aBC') u ...
- 屏蔽指定地区IP访问
<?php if ($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]) { $ip = $HTTP_SERVER_VARS["HT ...
- OpenResty,X-WAF防火墙相关
>>OpenResty<< >>Lua教程<< >>反向代理百度百科<< >>X-WAF配置指南<<
- OpenStack☞网关协议
一 动态页面与静态页面区别 静态页面:每一个网页都有一个固定的URL,且网页的URL以.html..htm..shtml等常见的形式为后缀. 网页内容已经发布到网站服务器上,无论是否有用户访问,每个静 ...
- 唯一索引与非唯一索引区别(UNIQUE INDEX, NON-UNIQUE INDEX)
索引是我们经常使用的一种数据库搜索优化手段.适当的业务操作场景使用适当的索引方案可以显著的提升系统整体性能和用户体验.在Oracle中,索引有包括很多类型.不同类型的索引适应不同的系统环境和访问场景. ...
- H3C 专线连接模型
- H3C 无线覆盖原则-蜂窝式覆盖
- [C#] 用ServiceStack读写redis的性能问题
ServiceStack.Redis有个方法叫 AddRangeToList,这个方法是有性能问题的.这个方法的实现代码如下: public void AddRangeToList(string li ...