解构赋值
从python抄袭的好吧
解构赋值可以将-值从数组-或-属性从对象-提取到不同的变量中。
//es5
let url=options.url
let method=options.method
let body=options.body
...
--------
es6
let{url,method,body}=options
复制代码
let [a=0,b=0]=[2,3] //0是默认值
复制代码
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
复制代码
交换变量
[a, b] = [b, a] //注意括号和方括号开头记得在在上一行加;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
复制代码
给新的变量名赋值
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
复制代码
let和const
let
- 只能声明一次,但可以二次赋值
- let没有变量提升
- 作用域在{}内-块级作用域
{
let a = 1
console.log(a)
a = 2
console.log(a)
} //ok
复制代码
临时死区(Temporal Dead Zone)
js引擎在扫描代码发生var声明的变量时候,会将声明提升到作用域顶部,而let和const则放在Temporal Dead Zone中,当执行了声明变量后,才能使用,否则将会报错xxx is not defined。通俗来说,如果你不声明就用会直接报错
{
console.log(a)
let a = 1
} //a is not defined
复制代码
const
- 基本和let一样,唯一区别就是只能赋值一次,声明的时候必须赋值哟~
{
const a = 1
console.log(a)
a = 2
console.log(a)
} //报错哦~~~
复制代码
箭头函数
见函数这篇文章 箭头函数
参数
默认参数
ES5
假如我们只传了一个参,或者根本没有传参,ES6出现之前我们一般这样写,
function foo(a,b){
return a+b
}
foo() //NaN
复制代码
为了避免这种情况,我们设置默认参数
function foo(a,b){
a = a || 0
b = b || 0
return a+b
}
foo() //0
复制代码
ES6
function foo(a=0,b=0){
return a+b
}
foo() //0 好用多了-.-,麻烦js速度把ruby和python抄完
复制代码
剩余参数
ES5
function foo(message){
let result=0
for(let i=1;i<arguments.length;i++){
result+=arguments[i]
}return message+result
}
foo('全部参数相加=',1,2,3,4,5,6) //"全部参数相加=21"
复制代码
ES6
function foo(message,...array){
result=array.reduce((a,b)=>a+b)
return message+result
}
foo('全部参数相加=',1,2,3,4,5,6) //"全部参数相加=21"
复制代码
如果我不想用...array
function foo(message){
let args=[].slice.call(arguments) //ES5用把伪数组变成真数组
let array=args.slice(1)
result=array.reduce((a,b)=>a+b)
return message+result
}
foo('全部参数相加=',1,2,3,4,5,6) //"全部参数相加=21"
复制代码
ES6提供了新的方法
let args=[].slice.call(arguments) //ES5
let args=Array.from(arguments) //ES6
let args=[...arguments] //ES6
复制代码
扩展语句
扩展语法允许一个表达式在期望多个参数(用于函数调用)或多个元素(用于数组字面量)或多个变量(用于解构赋值)的位置扩展。//就很绕,领悟精神就好
let array1=[1,2,3,4,5,6]
let [a,b,c,...array2]=array1
console.log(array2) //[4, 5, 6]
复制代码
let array1=[2,3,4]
let array2=[1,...array1,5]
console.log(array2) //[1,2,3,4,5,6]
复制代码
模版字符串(Template literals)
模板字面量(Template literals) 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能
多行字符串
`
dqwerte
werwer
tert
` //反引号,包含4个回车
复制代码
字符串插值
var a = 5
var b = 10
console.log(`10+5 is ${a + b}`) //10+5 is 15
复制代码
函数接字符串
领悟一下,styled-component 就是用的这个语法
let name="bibi"
let person="good people"
function fn(){
let string=arguments[0] //arguments={0:[ "","是一个"," "],1:"bibi",2:"people",length:3,........}
let who=arguments[1]
let attrs=arguments[2]
if(name === 'bibi'){
return name +string[1] +'good boy'
}else{
return name + string[1]+ 'bad boy'
}
}
fn`${name} 是一个 ${person}`
复制代码
字面量加强
更安全的二进制
更安全的二进制字面量
0b1111101
0B1111101
复制代码
更安全八进制
更安全的八进制字面量
0O767
0o767
复制代码
完全支持unicode
由于历史原因,js使用的usc-2编码只能支持2个字节的字符,从es6开始完全支持unicode
String.fromCodePoint //码点转字符串
String.prototype.codePointAt //字符串转unciode码点
复制代码
symbol
Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。
每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。更进一步的解析见
我觉得没什么卵用
let a = {
a:'qwerfvqe'
b:'qwehdfber',
c:'gwegweyhgh'
}
//不是一回事吗
复制代码
迭代器和生成器
迭代器
一个迭代器对象 ,知道如何每次访问集合中的一项, 并跟踪该序列中的当前位置。在 JavaScript 中 迭代器是一个对象,它提供了一个next() 方法,用来返回序列中的下一项。这个方法返回包含两个属性:done和 value。
function 迭代器(){
let _value = 0
let max = 10
return {
next(){
if(_value > max){ throw new Error('这个版本我们还没研究出来')
_value += 1
if(_value === max){
return {value:_value,done:ture}
}else{
return {value:_value,done:false}
}
}
}
}
复制代码
生成器
虽然自定义的迭代器是一个有用的工具,但由于需要显式地维护其内部状态,因此需要谨慎地创建。Generators提供了一个强大的选择:它允许你定义一个包含自有迭代算法的函数, 同时它可以自动维护自己的状态。
GeneratorFunction 是一个可以作为迭代器工厂的特殊函数。当它被执行时会返回一个新的Generator对象。
就是用来生成迭代器的,是迭代器的语法糖
function* 生成器() {
var value = 0
while(true)
value += 1
yield value //每次在yield这里会停顿,调用next()会并抛出一个值,
}
var gen = 生成器()
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
复制代码
可迭代对象
一个定义了迭代行为的对象,比如在for...of中循环了哪些值。一些内置类型,如Array或Map具有默认的迭代行为,而其他类型(如Object)没有。
可迭代对象必须具有带 Symbol.iterator
键的属性
Object是不可迭代的,因为Object原型链上并没有Symbol.iterator
这个属性
var myIterable = {}
myIterable[Symbol.iterator] = function* () {
yield 1
yield 2
yield 3
}
for (let value of myIterable) {
console.log(value)
}
// 1
// 2
// 3
复制代码
for of
for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环
推荐在循环对象属性的时候,使用for...in,在遍历数组的时候的时候使用for...of。
for...in循环出的是key,for...of循环出的是value
for(let value of array){
console.log(value)
}
复制代码
for...in不能循环不可迭代对象比如object,可以用object.keys()把属性变为数组在进行循环
var obj={
a:'a1',
b:'b2',
c:'c3'
}
for(let key of Object.keys(obj)){
console.log(key) //使用Object.keys()方法获取对象key的数组
}
复制代码
或者这样输出value
var obj={
a:'a1',
b:'b2',
c:'c3'
}
obj[Symbol.iterator] = function*(){
let keys = Object.keys(obj) //['a','b','c']
for(let i = 0;i < keys.length;i++){
yield obj[keys[i]]
}
}
for(var value of obj){
console.log(value)
}
复制代码