let和const
我把它单拿出来讲了讲:
变量提升+let+const
解构赋值
什么是解构赋值?
举一个简单的例子,JavaScript中的数组如果要把第一个和第二个元素换位置,需要借助一个临时变量。
而解构赋值就是一种表达式,可以把属性/值从对象/数组中取出来,并进行赋值,可以使运算更为简单。
解构赋值是针对数组和对象来操作的。
数组
javascript的数组定义:
let a=[1,2,3];
let b=[1,,2];//b[1]=undefined
let c=["one","two","three"];
let d;
d=[4,5,6];
基本上有这几种定义方式
解构数组定义:
let [a,b]=[1,2];//a=1,b=2
let foo=[1,2,3];
let [a,b,c]=foo;//a=1,b=2,c=3
let [a,b]=foo;//a=1,b=2
let a,b;
[a,b]=[1,2];//a=1,b=2
let a,b;
//防止出现undefined,所以给变量默认值
//首先会与后侧进行匹配,如果匹配结果是undefined,触发默认值
[a=1,b=5]=[7];
//a=7,b=5
[a=1,b=5]=[,7];
//a=1,b=7
[a=1,b]=[7];
//a=7,b=undefined
let [a,...b]=[1,2,3];//a=1,b=[2,3]
//剩余元素必须是数组的最后一个元素
交换变量:
//交换变量
//javascript
var foo=[1,2];//foo[0]=1,foo[1]=2
var i;
i=foo[0];
foo[0]=foo[1];
fpp[1]=i;//foo=[2,1];
//解构
var [a,b]=[1,2];
[a,b]=[b,a];//[a,b]=[2,1]
返回数组:
//返回数组
//javascript
function f(){
var a=[1,2];
return a;
}
var b=f();//b[0]=1,b[1]=2
//解构
function f(){
return [1,2,3];
}
var [a,b,c]=f();//a=1,b=2,c=3
var [a,,c]=f();//a=1,c=3
对象
//访问
var person={name:"lucy",age:16,color:"red",dad:"bob",mom:"lili"};
person.name;//person["name"]
//解构
var {name,age,color}=person;//左侧变量名必须要和person中的变量名相同
//name="lucy",age=16,color="red"
var {age:a,dad:b}=person;//a=16,b="bob"赋值给新变量
var {color="green",mom}={mom:"lili"};
//左边的目标变量去匹配右边源变量,结果为undefined,设为默认值
//color="green",mom="lili"
var {color:c="green",mom:d}={mom:"lili"};
//c="green",d="lili"
下面我们可以看一个解构数组和对象的例子:
const metadata = {
title: 'Scratchpad',
translations: [
{
locale: 'de',
localization_tags: [],
last_edit: '2014-04-14T08:43:37',
url: '/de/docs/Tools/Scratchpad',
title: 'JavaScript-Umgebung'
}
],
url: '/en-US/docs/Tools/Scratchpad'
};
let {
title: englishTitle, // rename
translations: [
{
title: localeTitle, // rename
},
],
} = metadata;
console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
我们先分析一下
metadata
的结构:
metadata
是一个对象,里面有三个属性,分别是title
、translations
、url。其中translations
又是一个数组,数组中只有一个元素,是个对象,对象包含5个属性
我们的目的是得到metadata
的title
属性以及metadata
的translations
的title
。
在上面我们已经给出了用解构的方式获得,我们只要按照metadata
的层次来写就好。
那么我们用最原始的方法可以得到吗?也可以。
var a=metadata.title;//a='Scratchpad'
var b=metadata.translations[0].title;//b='JavaScript-Umgebung'
那么解构赋值到底有什么快捷的地方? 在解构赋值语法之前,想获得对象或者数组中的所有值,需要把每项解构出来,再分别进行赋值。 有了解构赋值语法之后,可以把数组所有项或者对象所有属性解构出来的同时,进行赋值。
var a=[1,2,3];
var man={name:"bob",age:26};
var one=a[0];
var two=a[1];
var three=a[2];
var name=man.name;
var age=man["age"];
var [one,two,three]=a;
var {name,age}=man;
解构直接把上面几行代码用两行搞定。
可以参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Symbol数据类型
Symbol
表示独一无二的值,不是对象,不能new Symbol(),是数据类型
公式:let sym=Symbol("key");//名称=Symbol(键值);
从例子来说:
var a=1,b=1;
var x=Symbol(1),y=Symbol(1);
console.log(a===b);
console.log(x===y);
console.log(x==y);
看出:a 和 b是完全相等的,类型和值都一样,但 x 和 y 都是不等的,类型和值都不等,虽然他们看起来是一样的,因为他们是Symbol类型
,是独一无二的(Symbol一定要大写)。
Symbol最大的用处就是作为对象唯一的属性名来用。对象肯定有很多属性,那么我需要用唯一一个属性可以来区分这么多对象,Symbol就是最好的选择,Symbol类似于数据库中的主键。
//使用Symbol作为属性名
let sym=Symbol("key");
//写法1
let a={age:16,color:"red",[sym]:"b"};
console.log(a,a[sym],a.sym);
写法2
let a={age:16,color:"red"};
a[sym]="b";
//写法3
let a={age:16,color:"red"};
Object.defineProperty(a,sym,{value:"b"});
注意:
let sym=Symbol("key");
let a={age:16,color:"red",[sym]:"b"};
for(let i in a){
console.log(i);
}
像是for…in(for…of)的循环,无法获取到Symbol属性。
获得Symbol属性:
//Symbol属性赋值给了sym,属性值是b,获得属性是获得sym的内容
console.log(Object.getOwnPropertySymbols(a));
console.log(Reflect.ownKeys(a));
方法:
let red=Symbol("red");//red是symbol的键值,也叫自身描述字符串,red是该symbol的名称
let red2=Symbol.for("red2");
let green=Symbol.for("green");
//Symbol.for(key)方法会在全局的Symbol注册表中搜索是否含有以key作为键值的Symbol值,
//如果有则返回找到的Symbol值,没有就新建一个以key为键值的Symbol值,并放入注册表
console.log(red2);
console.log(green);
console.log(red);
//Symbol.keyFor(sym)用来检测在注册表中该字符串参数作为名称的 Symbol 值是否已被登记
//返回一个已登记的 Symbol 类型值的 key
console.log(Symbol.keyFor(red));
思考:
为什么Symbol.keyFor(red)
会显示undefined呢?
这就是
Symbol
和Symbol.for()
的区别,Symbol不会把新建的Symbol值放入全局注册表,但Symbol.for()会。
所以注册表中其实是没有red这个Symbol的
Map和Set
我们先来了解键值对的概念:
"key":"value"
,这种的结构大家基本都见过吧,尤其在对象中。这就是一个键值对,key是键,value是值。一个key只能对应一个value。
Map
Map对象就是保存键值对的结构。
var m=new Map();// 创建Map对象
//Map初始化
//第一种
m.set('bob',"59");
m.set('lili',89);
m.set(function(){},"函数");
m.set({},"对象");
var x=m.get('lili');
//第二种
var bob="bob";
var lili="lili";
var fun=function(){};
var se={};
m.set(bob,"59");
m.set(lili,"89");
m.set(fun,"函数");
m.set(se,"对象");
//第三种
var m=new Map([["bob","59"],["lili","89"],[function(){},"函数"],[{},"对象"]]);
console.log(m);
读取值:
var m=new Map();// 创建Map对象
//Map初始化
//第一种
m.set('bob',"59");
m.set('lili',89);
m.set(function(){},"函数");
m.set({},"对象");
//读取值
console.log(m.get('bob'));//59
console.log(m.get({}));//undefined
console.log(m.get(function(){}));//undefined
//第二种
var bob="bob";
var lili="lili";
var fun=function(){};
var se={};
m.set(bob,"59");
m.set(lili,"89");
m.set(fun,"函数");
m.set(se,"对象");
//读取值
console.log(m.get(bob));//59
console.log(m.get("bob"));//bob="bob";//59
console.log(m.get(fun));//函数
// //第三种
var m=new Map([["bob","59"],["lili","89"],[function(){},"函数"],[{},"对象"]]);
console.log(m);
//读取值
console.log(m.get("bob"));//59
console.log(m.get({}));//undefined
console.log(m.get(function(){}));//undefined
我们发现,读取值的时候,如果我们没有把键赋值给一个变量,然后用变量去读取,尤其是键为{}
和function(){}
时,会出现undefined
。而像bob
这种没有赋值变量的,却也可以找到。这是为什么?
console.log({}==={});//false
console.log(function(){}===function(){});//false
console.log([]===[]);//false
可以参考:https://blog.csdn.net/hb_zhouyj/article/details/78343021
Map的属性和一些方法:
Map.size
; 键值对的数量Map.clear()
; 移除所有键值对Map.delete(key)
; 如果存在key,删除并返回true,如果没有返回falseMap.entries()
; 返回一个对象。它按插入顺序包含了Map对象中每个元素的 [key, value] 数组。Map.forEach(callback,thisArg)
; thisArg可选,callback 执行时其 this 的值。
callback:function(value,key,map)
:对 Map 中真实存在的每一个元素执行一次参数中提供的回调函数
Map.has(key)
; 返回一个布尔值,表示Map实例是否包含键对应的值Map.keys()
; 返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的键 .Map.values();
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的值 。
Map的遍历:
//for...of方法 for...in不能用于Map遍历
for(let [key,value] of m.entries()){
console.log(key+"="+value);
}
for(let [key,value] of m){
console.log(key+"="+value);
}
for(let key of m.keys()){
console.log(key);
}
for(let value of m.values()){
console.log(value);
}
//forEach()
m.forEach(function(value,key,Map){
console.log(Map+":"+key+"="+value);
},this);
Map和数组:
在我们构造Map时的第三种方法中,就是用二维数组构造了一个Map对象。
var m=new Map([["bob","59"],["lili","89"],[function(){},"函数"],[{},"对象"]]);
var arr=[["bob","59"],["lili","89"],[function(){},"函数"],[{},"对象"]];
var m=new Map(arr);//和上面的结果一样
//把Map转换成二维数组
console.log(Array.from(m));//Array.from(被转换的对象,map函数,map函数中this指代对象)
//合并map和map,map和数组
var m2=new Map([[1,"one"],["bob","100"]]);
var result=new Map([...m,...m2]);//如果有重复的键值,则后面的会覆盖前面的
console.log(result);
var r2=new Map([...m,...m2,[2,"two"]]);
console.log(r2);
//克隆map
var m3=new Map(m);
console.log(m3);
展开操作符:
[...new Map(m)];//可以直接把Map转换为数组
Set
Set
对象是储存值的集合,并且值是唯一的。
Set
属性和方法:
Set.size
; 值的数量Set.add(value)
; 在Set尾部插入新的值,并返回该对象Set.clear()
; 移除所有元素Set.delete(value)
; 如果存在value,删除并返回true,如果没有返回falseSet.entries()
; 和Map类似,每个值的键和值相等 [value,value]Set.foreach(callback,thisArg)
; 参考MapSet.has(value);
返回一个布尔值,表示该值在Set中存在与否Set.keys();Set.values();
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值
Set的遍历、转换数组等等都和Mp是类似的。
用Set达到集合的交差并补
Proxy和Reflect
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
https://es6.ruanyifeng.com/#docs/reflect
字符串新方法
- 子串识别:判断字符串中是否含有某子串,可以规定起始位置
string1.includes(string2)
:返回布尔值,判断是否找到参数字符串。string1.startsWith(string2)
:返回布尔值,判断参数字符串是否在原字符串的头部。string1.endsWith(string2)
:返回布尔值,判断参数字符串是否在原字符串的尾部。
- 字符串重复
string.repeat(number)
:返回新的字符串,表示将字符串重复指定次数返回。number:
小数
:向下取整 3.2=>30~-1
:=>0NaN
:=>0负数/Infinity
:报错字符串
:=>数字
- 字符串补全
oldstring.padStart(newstring_min_length,string):
用string
从左侧
补全原字符串(oldstring),生成新的字符串长度为newstring_min_length
oldstring.padEnd(newstring_min_length,string)
:用string
从右侧
补全原字符串(oldstring),生成新的字符串长度为newstring_min_length
注意:
如果newstring_min_length<=oldstring.length
,返回原字符串
如果oldstring.length+string.length>newstring_min_length
,截去超出位数的补全字符串
- 模板字符串
用 反引号声明模板字符串,模板字符串可以定义多行字符串,在字符串中用
${}
里面可以放变量,表达式,函数。在模板字符串中空格和换行都是会被保留的。
var string="i love china";
console.log(string.includes("china"));
console.log(string.startsWith("china"));
console.log(string.endsWith("china"));
console.log(string.repeat(3.7));
console.log(string.padStart(20,"h"));
let s1=`hey,
boy !`;
console.log(s1);
let name='bob',age=16;
function fun(){
return 'hello!!';
}
let s2=`my name is ${name} and I am ${age} years old! ${fun()}`;
console.log(s2);
ES6第二部分:https://blog.csdn.net/yiersan__/article/details/107730444