ES6学习笔记



let 命令:let声明的变量只在它所在的代码块有效。
 {
  let a=10;
  var b=1;
 }
 let不存在变量提升,var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined.let命令改变了
 语法行为,必须先声明后使用。
 let不允许重复声明。
 ES6 允许块级作用域的任意嵌套。
 const的作用域与let命令相同:只在声明所在的块级作用域内有效。
 
 ES5 只有两种声明变量的方法:var命令和function命令。ES6除了添加let和const命令,后面章节还会提到,
 另外两种声明变量的方法:import命令和class命令。所以,ES6 一共有6种声明变量的方法。
 
 ES6开始,全局变量逐步与顶层对象的属性脱钩。
 var a=1;
 window.a    //1
 
 let b=1;
 window.b   //undefined
 
 
 变量的解构赋值:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
 以前:
 let  a=1;
 let b=2;
 let c=3;
 ES6允许这样写:
 let[a,b,c]=[1,2,3];
 本质上属于“模式匹配”,如果匹配不成功,则返回undefined.
 
 另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
 let[x,y]=[1,2,3];
 console.log(x);      //1
 console.log(y);        //2
 
 解构不仅可以用于数组,还可以用于对象。
 
 字符串的扩展:
    传统上,JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新方法。
-includes():返回布尔值,表示是否找到了参数字符串。
-startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
-endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

  repeat()
  repeat方法返回一个新字符串,表示将原字符串重复n次。
   'x'.repeat(3)         //"xxx"
    'hello'.repeat(2)    //"hellohello"
 
  ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。
  padStart()用于头部补全,padEnd()用于尾部补全。
 
 
  模板字符串:
  传统的javascript语言,输出模板通常是这样写的。
      $('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);
上面这种写法相当繁琐不方便,ES6引入了模板字符串解决这个问题。
      $("#result").append(`
   There are <b>${$basket.count}</b>items
     in your basket,<em>${basket.onSale}</em>
   are on sale!
   `);
  模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,
  也可以用来定义多行字符串,或者在字符串中嵌入变量。
 
 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。
 
 ES6 在Number对象上,新提供了Number.isFinite()和Number.isNaN()两个方法。

  Number.isFinite()用来检查一个数值是否为有限的(finite)。
  Number.isFinute(15);   //true
  Number.isFinute(0.8);       //true
  Number.isFinute(NaN);       //false
 
  ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。
  // ES5的写法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45

// ES6的写法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45
这样做的目的,是逐步减少全局性方法,使得语言逐步模块化。
Number.parseInt === parseInt // true
Number.parseFloat === parseFloat // true

Number.isInteger()用来判断一个值是否为整数。需要注意的是,
在 JavaScript 内部,整数和浮点数是同样的储存方法,
所以3和3.0被视为同一个值。
    Number.isInteger(25) //true
 Number.isInteger(25.0)  //true
 Number.isInteger(25.1)    //false
 
 
函数的扩展
      1.函数参数的默认值
   ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。
    function log(x,y){
     y=y||'World';
     console.log(x,y);
    }
    log('Hello');   // Hello World
    log('Hello','China') // Hello China
    log('Hello','')       // Hello World
上面代码检查函数log的参数y有没有赋值,如果没有,则指定默认值为World。
这种写法的缺点在于,如果参数y赋值了,但是对应的布尔值为false,
则该赋值不起作用。就像上面代码的最后一行,参数y等于空字符,结果被改为默认值.
为了避免这个问题,我们需要判断一下参数y是否被赋值,如果没有,再等于默认值。
    if(typeof y==='undefined'){
   y='World';
 } 
ES允许为函数的参数设置默认值,即直接写在参数定义的后面。
      function log(x,y='World'){
     console.log(x,y);
   }
   log('Hello');   // Hello World
   log('Hello','China')  //Hello China
   log('Hello','')   //Hello
  
  
   对象的扩展:
       Object.is() 与严格比较运算符(===)的行为基本一致,
    不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
   
+0 === -0 //true
NaN === NaN // false

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

Object.assign()方法用于对象的合并,将源对象的所有可枚举属性,复制到目标对象。

var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

ES5 引入了Object.keys方法,返回一个数组,
成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

Object.keys(),Object.values(),Object.entries()

ES5 引入了Object.keys方法,返回一个数组,
成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

ES2017 引入了跟Object.keys配套的Object.values和Object.entries,
作为遍历一个对象的补充手段,供for...of循环使用。
  let {keys,values,entries}=Object;
  let obj={a:1,b:2,c:3};
  for (let key of keys(obj)){
   console.log(key);
  }
  for(let value of values(obj)){
    console.log(value);
  }
  for(let[key,value] of entries(obj)){
    console.log([key,value]);
  }
 
 Object.values方法返回一个数组,
 成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
 var obj = { foo: 'bar', baz: 42 };
Object.values(obj)
// ["bar", 42]

Object.entries方法返回一个数组,
成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
var obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,
前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

let s = Symbol();
typeof s
// "symbol"


Set和Map数据结构

1.Set
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set 本身是一个构造函数,用来生成 Set 数据结构。
 const s=new Set();
 [2,3,5,4,5,2,2].forEach(x=>s.add(x));
 for(let i of s){
  console.log(i);
 }
 向Set加入值的时候,不会发生类型转换,所以5和"5"是两个不同的值。
 Set内部判断两个值是否不同,使用的算法叫做“Same-value equality”,
 它类似于精确相等运算符(===),主要的区别是NaN等于自身,
 而精确相等运算符认为NaN不等于自身。
 let set = new Set();
 let a = NaN;
 let b = NaN;
 set.add(a);
 set.add(b);
  set // Set {NaN}
 上面代码向 Set 实例添加了两个NaN,但是只能加入一个。这表明,在 Set 内部,两个NaN是相等。
Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。
下面先介绍四个操作方法。
add(value):添加某个值,返回Set结构本身。
-delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
-has(value):返回一个布尔值,表示该值是否为Set的成员。
-clear():清除所有成员,没有返回值。
s.add(1).add(2).add(2);
// 注意2被加入了两次

s.size // 2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2) // false


Set 结构的实例有四个遍历方法,可以用于遍历成员。
-keys():返回键名的遍历器
-values():返回键值的遍历器
-entries():返回键值对的遍历器
-forEach():使用回调函数遍历每个成员
let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

WeakSet 结构


Map结构
const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

WeakMap
WeakMap结构与Map结构类似,也是用于生成键值对的集合。


Proxy
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,
可以译为“代理器”。
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。
var proxy = new Proxy(target, handler);
Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,
target参数表示所要拦截的目标对象,handler参数也是一个对象,
用来定制拦截行为。
var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});
proxy.time // 35
proxy.name // 35
proxy.title // 35

如果handler没有设置任何拦截,那就等同于直接通向原对象。
var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a // "b"


Generator 函数的语法
yield在英语里的意思就是“产出”)。
function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}
var hw = helloWorldGenerator();
下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。
也就是说,每次调用next方法,
内部指针就从函数头部或上一次停下来的地方开始执行,
直到遇到下一个yield表达式(或return语句)为止。换言之,
Generator 函数是分段执行的,yield表达式是暂停执行的标记,
而next方法可以恢复执行。
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }


ES6的Class
JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。
基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,
新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
上面的代码用 ES6 的class改写,就是下面这样
//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

ES6 的类,完全可以看作构造函数的另一种写法。
class Point {
  // ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true

构造函数的prototype属性,在 ES6 的“类”上面继续存在。
事实上,类的所有方法都定义在类的prototype属性上面。


Class的继承,extends关键字实现继承。
class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值