es6入门知识概要

前言

最近需要使用react进行开发,由于react需要ES6的语法支持,所以希望在进行React学习之前,先了解下ES6的一些特性.(本文主要来源于阮一峰的教程)

一、块级变量 let/const

ES6中支持声明代码块级别的变量,主要有两种方式,let和const,let声明变量,const声明常量。

let

1、只能在声明代码所在的代码块中使用

function hello(){
let a =1;
}
alert(a);

代码会报错

ReferenceError: alert is not defined
   at Object.<anonymous> (/code/main.js:4:1)
   at Module._compile (module.js:649:30)
   at Object.Module._extensions..js (module.js:660:10)
   at Module.load (module.js:561:32)
   at tryModuleLoad (module.js:501:12)
   at Function.Module._load (module.js:493:3)
   at Function.Module.runMain (module.js:690:10)
   at startup (bootstrap_node.js:194:16)
   at bootstrap_node.js:666:3

2、在同一个代码块(不包含子块)只能声明一次

相同代码块


{
  let a ="sss";
  let a=1; //报错
}

不同代码块

let a=1;
{
    let a ="sss"; //不报错
}

3、不存在变量提升

使用let声明的变量,只能在声明代码之后才能使用

4、暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

const

const声明一个只读的常量。一旦声明,常量的值就不能改变。
const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
本质
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

二、函数的扩展

2.1、箭头函数

ES6 允许使用“箭头”(=>)定义函数。

var f = v => v;

// 等同于
var f = function (v) {
  return v;
};

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。

var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
建议采用这种方式

var sum = (num1, num2) => { return num1 + num2; }

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

// 报错
let getTempItem = id => { id: id, name: "Temp" };

// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });

箭头函数的一个用处是简化回调函数。

// 正常函数写法
var result = values.sort(function (a, b) {
  return a - b;
});

// 箭头函数写法
var result = values.sort((a, b) => a - b);

三、Class的使用

3.1、类的声明

class Point {
  constructor() {
    // ...
  }

  toString() {
    // ...
  }

  toValue() {
    // ...
  }
}

// 等同于

Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

注意点:

  1. 方法可以直接声明,不用function修饰
  2. 类的方法都定义在prototype对象上面
  3. 类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。
  4. constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
  5. 与 ES5 一样,类的所有实例共享一个原型对象。
  6. 使用#支持私有属性和私有方法
  7. name 属性
  8. 使用static声明静态方法,调用时也是通过类直接调用

3.2、继承

ES6使用extends关键字实现类之间的继承
注意点:
1. Object.getPrototypeOf可以获取父类
2. 类的 prototype 属性和__proto__属性
1)子类的__proto__属性,表示构造函数的继承,总是指向父类。
2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

四、模块化

4.1、export

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。

4.1.1 直接输出

方式一:
export变量:

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

export函数:

export function multiply(x, y) {
  return x * y;
};

4.1.2使用{}输出

方式二:
export变量

var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year};

export函数

function v1() { ... }
function v2() { ... }

export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

4.1.3注意事项

  1. 另外,export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
  2. 建议使用{}方式
  3. export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错

4.2、import

4.2.1、import指定加载

import {firstName, lastName, year} from './profile.js';

4.2.2、全部加载

除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。

下面是一个circle.js文件,它输出两个方法area和circumference。

export function area(radius) {
  return Math.PI * radius * radius;
}

export function circumference(radius) {
  return 2 * Math.PI * radius;
}

现在,加载所有模块方法

import * as circle from './circle';

console.log('圆面积:' + circle.area(4));
console.log('圆周长:' + circle.circumference(14));

4.2.3、注意点

  • 模块文件位置
    import后面的from指定模块文件的位置,可以是相对路径,也可以是绝对路径,.js后缀可以省略。如果只是模块名,不带有路径,那么必须有配置文件,告诉 JavaScript 引擎该模块的位置。
import {myMethod} from 'util';

上面代码中,util是模块文件名,由于不带有路径,必须通过配置,告诉引擎怎么取到这个模块。

  • import语句会执行所加载的模块,因此可以有下面的写法
import 'lodash';

上面代码仅仅执行lodash模块,但是不输入任何值

4.2.4、export default

使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。

为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

// export-default.js
export default function () {
  console.log('foo');
}

上面代码是一个模块文件export-default.js,它的默认输出是一个函数。

其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

import customName from './export-default';
customName(); // 'foo'

上面代码的import命令,可以用任意名称指向export-default.js输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时import命令后面,不使用大括号。

export default命令用在非匿名函数前,也是可以的。

// export-default.js
export default function foo() {
  console.log('foo');
}

// 或者写成

function foo() {
  console.log('foo');
}

export default foo;

注意:
一个模块只能有一个default输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值