ES6

作者: 苦瓜_6 | 来源:发表于2018-06-25 14:21 被阅读0次

let 和 const

let 的特点

  • let 的作用域在最近的 {} 之间
  • 如果在 let a 之前使用 a ,那么报错(Temp Dead Zone)
  • 如果重复let a , 会报错
  • let 存在块级作用域

let 循环

for(let i = 0; i < 5;i++){
console.log(i)  //  块里面的i  = 圆括号里面 i 的值
}

console.log(i) // Uncaught ReferenceError: i is not defined

const 特点

  • const 的作用域在最近的 {} 之间
  • 如果在 const a 之前使用 a ,那么报错(Temp Dead Zone)
  • 如果重复const a , 会报错
  • 只有一次赋值机会,并且必须在声明的时候立马赋值
  • const声明创建一个值的只读引用,在引用内容是对象的情况下,可以改变对象的内容:
let user = { name: 'ZhangSan', age: 21 };
const USER_A = user;
console.log("USER_A :", USER_A ); // user: {name: "ZhangSan", age: 21}
user.age = 18;
console.log("USER_A :", USER_A ) // user: {name: "ZhangSan", age: 18}

解构赋值

数组的解构赋值

  • 匹配 [ b, a ] = [ a, b ]
let [a,b,c] = [1,2,3] ;
console.log(a,b,c) //  1  2  3 

let[a,[b],c] = [2,[3],4];
console.log(a,b,c)  // 2,3,4
let [a,b,...rest] = [10,20,30,40,50]
console.log(rest)   //   [30, 40, 50]
  • 交换变量
let a = 1;
let  b = 2;
[a,b] = [b,a];
console.log(a,b)    //  2 1
  • 默认值
let [a,b=2] = [3];
a // 3
b // 2    使用默认值
let [a,b=2] = [3,4];
a // 3
b //  4   有对应数值,使用对应数值

undefined 和null 的区别:

var [a,b,c] = [1,2]
console.log(a,b,c) //  1  2  undefined 

var [a,b,c] = [1,2, null]
console.log(a,b,c) //  1  2  null 
let[a=2,b=3] = [undefined, null]
a // 2
b //  null
  • 函数传参
let arr = [1,2];
function test([a,b]) {
  console.log("a: " + a); // a: 1
  console.log("b: " + b) //  b: 2
}
test(arr)

对象的解构赋值

  • 对象匹配 let { a, b, c } = objABC
let { name , age} = {name: 'xxx',age: 18};
name //   xxx
age // 18
  • 对象匹配的同时重命名
let { name : username, age} = {name: 'xxx',age: 18};
username //   xxx
age // 18
  • 对象匹配 —— 改变原来的值
let name = 'ZhangSan';
let obj  = {name: 'xxx',age: 18};
console.log(name); //   ZhangSan
({ name, age } = obj ) ; // 这里要用()包住,因为大括号会被解析成一个代码块报错
console.log(name) //  xxx
  • 指定默认值并重命名
let {a: A=1, b=2 } = {a: 99}
console.log(A) //  99 
console.log(b) //  2
  • 对象浅拷贝
let obj1  = { name: 'xxx',age: 18,others: {
fruits: 'xx1', book: 'wrrr' }   };
let obj2 = {...obj1};
console.log(obj2)    //  {name: "xxx", age: 18,others: {fruits: 'xx1', book: 'wrrr' }}
  • 对象合并 ...
let obj1  = {p1: 1, p2: 2};
let obj2 = {p2: 30, p3: 99};
let obj3 = Object.assign({},obj1,obj2);
console.log(obj3) //     {p1: 1, p2: 30, p3: 99}
let obj4 = {...obj1,...obj2};
console.log(obj4) //   {p1: 1, p2: 30, p3: 99}

参数处理

默认参数值

函数默认参数允许在没有值或undefined被传入时使用默认形参。

function sum(a=0,b=0){
       console.log('a:'+a);
       console.log('b:'+b);
        return a + b
}
sum(1) //  a:1     b:0   1
sum(2,6) //  a:2  b:6  8

上面的代码等价于:

function sum(a,b){
      a = a || 0;
      b = b || 0;
       console.log('a:'+a);
       console.log('b:'+b);
        return a + b
}

剩余参数

展开运算符

先来看一个数组的扩展:

var a = [1,2,3];
console.log(...a)  ; //  1 2 3
var b = [...a,99,88];
console.log(b);   //  对数组进行扩展 [1, 2, 3, 99, 88]
var c = b.concat(77,66);
console.log(c); // [1, 2, 3, 99, 88, 77, 66]
let arr1 = [1,2,3,4,5,6];
let [a,b,c,...arr2] = arr1;
console.log(arr2) //   [4, 5, 6]

... 相当于把数组拆开

  • 函数参数的扩展
function max(arr){
return Math.max(...arr)
};   // 求最大值
max([1,22,44,66,5,66,77,3,22,33,11,34])  //  77
function sort(...arr){
return arr.sort()
};
sort(1,2,5,3) //   [1, 2, 3, 5]
  • 类数组对象转数组
    ES5 写法是:
let newArr = Array.prototype.slice.call(ArrayLike)

ES6 写法如下:

let items = document.querySelectorAll('li');
Array.from(items).forEach((item) => console.log(item.innerText));

或者

let items = document.querySelectorAll('li');
[...items].forEach((item) => console.log(item.innerText))

模板字面量

多行字符串

let str = `
line1,
line2,
line3
`;      //    注意这里的 ` 不是单引号
str //  "
line1,
line2,
line3
"

字符串插值

let city = ' xxx';
let str =  ` Hi 
Welcome to ${city}.
`      //  同样的, 这里的 ` 不是单引号
str //  " Hi 
Welcome to  xxx.
"

可以用来拼接HTML:

var data = [1,2,3,4];
var liArr = data.map((item) => `<li class="xxx"> 内容 ${item}</li>`
).join('');
console.log(liArr);  // <li class="xxx"> 内容 1</li><li class="xxx"> 内容 2</li><li class="xxx"> 内容 3</li><li class="xxx"> 内容 4</li>

var html = `<ul>${liArr}</ul>`;
console.log(html)   //    <ul><li class="xxx"> 内容 1</li><li class="xxx"> 内容 2</li><li class="xxx"> 内容 3</li><li class="xxx"> 内容 4</li></ul>

带标签的模板字面量

如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,都可以通过该函数来对模板字符串进行操作处理。

let name = 'xxx';
let  score = 60;
let fn = function (){
console.log(arguments)
}
fn `${name} 的成绩是 ${score}`

运行结果如下:

image.png

let name = 'xxx';
let  score = 60;
let fn = function (){
   let str = arguments[0];
   let arg1 = arguments[1];
   let arg2 = arguments[2];
   if(arg2 >= 80){
        return arg1 + str +arg2 + ',再接再厉哦!'
    } else{
        return arg1 + str + arg2 +  ',要加油了哦!'
    }
}
fn `${name} 的成绩是 ${score}`
//   "xxx, 的成绩是 ,60,要加油了哦!"

把 name 和 score 改下:

name = 'x2';score = 90;
fn `${name} 的成绩是 ${score}`
//  "x2, 的成绩是 ,90,再接再厉哦!"

原始字符串

在标签函数的第一个参数中,存在一个特殊的属性raw,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。

function tag(strings) {
  console.log(strings.raw[0]);
}

tag`string text line 1 \n string text line 2`; 
 // string text line 1 \n string text line 2

原有字面量增强

  • 更安全的二进制字面量(0b1111101)
  • 更安全的八进制字面量(0o767)
  • 字符串支持 Unicode
    -- String.fromCodePoint
    -- String.prototype.codePointAt
  • 正则表达式字面量添加 Unicode 支持(u 标记)
  • 正则表达式添加 y 标记,支持粘滞匹配

对象属性加强

属性定义支持短语法 obj = { x, y }

ES5写法:

var a = 1;
var b = 4;
var obj = {a:a,b:b}  ;
obj  //  {a: 1, b: 4}

ES6写法:

let a = 1;
let b = 4;
let obj = {a,b}  ;
obj //   {a: 1, b: 4}

属性名支持表达式

动态属性名
原来的写法:

var name = 'a';
var obj = {};
obj[name] = 123;
obj //  {a: 123}

ES6:

let name = 'a';
let obj = {[name]: 123};
obj   //    {a: 123}

属性修饰符Object.defineProperty()

a === 1 && a ===2 && a === 3 问题

var  i = 0;
Object.defineProperty(window,'a',{
    get(){
      i += 1;
      return i
    }
})

a === 1 && a ===2 && a === 3   //  true

类 class

var Slider = {
append: function(){
      console.log(1)
     },
render: function(){
     console.log(2)
  }
}

ECMAScript 2015引入了一种对象方法的简短写法, "function" 关键字可以丢掉:

var Slider = {
append(){
   console.log(1)
  },
render(){
  console.log(2)
   } 
}

构造函数

class Cat {
constructor(name,personality){
this.name = name;
this.personality = personality;
} //  注意: 这里没有逗号
sayHi (){   //  这个函数会放在原型上
      console.log(`Hi,I'm a ${this.name}, I'm ${this.personality}`);
    }
}

var BritishShorthair  =  new Cat('BritishShorthair','docile');
console.log(BritishShorthair); //  {name: "BritishShorthair", personality: "docile"}
BritishShorthair.sayHi(); //  Hi,I'm a BritishShorthair, I'm docile

上面的代码等价于

function Cat(name,personality){
this.name = name;
this.personality = personality;
};
Cat.prototype.sayHi = function(){
console.log(`Hi,I'm a ${this.name}, I'm ${this.personality}`)
};
var BritishShorthair  =  new Cat('BritishShorthair','docile');
console.log(BritishShorthair); //   Cat {name: "BritishShorthair", personality: "docile"} 
BritishShorthair.sayHi(); //   Hi,I'm a BritishShorthair, I'm docile

class 共有属性不能是非函数:

  • 可以用原型写
    xxx.prototype.race = 'animal'
  • get
class Cat {
 constructor(name,personality){
   this.name = name;
   this.personality = personality;
   }
get race (){
  return 'animal'
  }
}
let BritishShorthair  =  new Cat('BritishShorthair','docile');
BritishShorthair.race  //   animal

但是 不能通过 BritishShorthair.race = newvalue来改

image.png

所以又要用到 set

class Cat {
 constructor(name,personality){
   this.name = name;
   this.personality = personality;
   this._race = `animal`;
   }
get race (){
  return this._race
  }
set race(value){
  this._race = value
 }
}

let BritishShorthair  =  new Cat('BritishShorthair','docile');

再修改就发现改成功了:


image.png

如果想让属性只读,就不写set


ES6 模块

用 import 和 export 写好之后,
可以用webpack 或者 parcel (推荐) 打包 ,然后引入

<script type="module" src="javascripts/app.js"></script>  <!-- 已支持 ES6 模块的浏览器 -->
<script nomodule src="dist/app.js"></script>              <!-- 不支持 ES6 模块的浏览器 -->

其他:
箭头函数
JS 中的 Symbol 是什么?

Generator函数的含义与用法
Thunk函数的含义与用法
co函数库的含义与用法
async函数的含义与用法
tj/co

相关文章

网友评论

      本文标题:ES6

      本文链接:https://www.haomeiwen.com/subject/qmwoeftx.html