ECMAScript6
- es6的声明6种方式
- es5中只有两中声明变量的方式,var命令和function命令
- es6除了添加let和const命令,还添加了两种声明变量的方法:import命令和class命令
var 命令
var a; // undefined var b = 1
- var定义的变量可以修改,如果不初始化会输出undefined
- var声明的变量在window上,使用let和const声明的变量,不会被放在window上
- 很多语言中有块级作用域,但js没有, 使用var声明的变量使用function来划分作用域为全局作用域和局部作用域,使用{}不能确定var的作用域,因此var声明的变量具有变量提升的效果
- var声明的变量的作用域是全局的或者是函数级的(局部作用域)
function命令
function add(a, b) { return a + b }
- 声明了一个add的新变量,并为其分配一个函数定义
- {}直接的内容被分配了add
- 函数内部的代码是以字符串存放在堆中的,不会被执行,为备将来调用的时候使用
const 命令
const a //报错,必须进行初始化 const b = 1
- const定义的变量不可修改,而且必须初始化
- 该变量是一个全局变量,或者模块内的全局变量
- 如果一个变量只有在声明时才被赋值一次,永远不会在其他的代码中被重新赋值,那么应该使用const
- 创建一个只读常量,在不同的浏览器中表现为不可修改,拥有块级作用域
- const的值是一个常量索引,也就是说,变量的名字在内存中的指针不可以改变,但是指针指向的变量的值是可以改变的
- const定义的变量不可修改,一般在require一个模块时候用或定义一些全局变量
- 可以在全局作用域或者函数内声明常量,但必须初始化常量
- 常量不能和它所在的作用域中其他变量或者函数重名
let 命令
let a // undefined let b = 1 function add (a, b) { return a + b } let c = add(1, 2)
- 需要javascript的严格模式
- 不存在变量的提升
- 不允许重复声明
- let声明的变量作用域在块级域中,函数内部使用let定义后,对函数外部无影响(块级作用域)
- 可以在声明时为变量赋值,默认为undefined, 没有变量提升,因此在声明之前无法使用(暂存死区)
exoprt/import 命令
[方式一]
export function foo() {} export var name = "anan" var bar = [1,2,3] export {bar} [方式二] function foo(){} var name = "anan" var var = [1, 2, 3] exoprt {foo, name, bar} [方式三] function foo() {} exoprt {foo as foo1} // 导出时时命名 [方式四] function foo() {} exoprt default foo [导入] import {foo} form "xxx" import fooFn from 'xxx' // 随意命名 export default function foo() {} export function bar() {} export function baz() {} import fooFn { bar, baz } from "module";
- es6中的模块就是一个js文件
- 主要有两种模块化方式:CMD和AMD
- import有变量提升的过程和var变量一样
class命令
-
es6之前js没有类的概念,但可以通过构造函数来时类的功能
function Person(name, age) { this.name = name this.age = age this.sayHello = function () { console.log("name:" + this.name) } } function Worker(job) { this.job = job this.sayJob = function () { console.log(this.job) } } Worker.prototype = new Person("anan", 20) // 利用原型链继承实现worker对Person方法和属性的继承 var teacher = new Worker("ananTea")
- 分析:
- 创建一个构造函数perosn,我么么可以认为是“类”, 其中两个属性是name和age,和一个类的方法sayHello
- 采用new实例化Person, 返回一个person对象
- Person的构造函数中有一个prototype方法,指向该构造函数的原型对象Person.prototype,该原型对象包含了两个默认的方法(constrcutor和__proto__), Person.prototype.constructor指向当前的构造函数,Person.prototype.__proto__指向创建Person.prototype对象的构造函数的原型对象
- 利用原型链的方式实现继承
- 分析:
-
es6中提供了class关键字,提供了对类的支持
class Person { constructor (name, age) { this.name = name this.age = age } sayHello() { console.log(this.name) } } var person = new Person("anan", 20) person.sayName() // anan
-
分析
-
class关键字定义了Person类,constructor为该类的构造方法 sayHello为类方法,在使用new创建一个实例对象perosn时,会自动调用constructor构造方法,传入参数,返回实例对象,this指向的就是该实例对象
-
使用class定义的类的实例化相当于给Person.prototype添加属性和方法,实际上定义子类的所有方法都是定义在prototype属性上的
-
严格模式,在类和模块的内部默认的就是严格模式
- constructor方法是类的默认方法, 通过new关键字声明对象时,自动调用该方法,一个类必须有constructor方法,如果不定义构造函数,则默认又一个构造函数
class Person { } class Person { constructor () { } }
- constructor方法默认返回实例对象(this),完全可以指定返回的另一个对象
class Person { constructor () { return Object.create(null) } } new Person() instanceof Person // false
- 类的实例对象:生成的实例对象的写法,与ES一样使用new命令,实例的属性除非显示定义在其本身,即this对象上,否则就是定义在原型上
class Person { constructor (name, age) { this.name = name this.age = age } sayHello () { return this.name } } var person = new Person("anan", 20) console.log(person.sayHello()) // anan person.hasOwnProperty("name") // true person.hasOwnProperty("age") // true person.hasOwnProperty("sayHello") // false person.__proto__.hasOwnProperty("sayHello") // true
-
-
name和age都是person的自身的属性,而sayHello是原型对象的属性
-
class的取值函数(getter)和存值函数(setter)
- 和es5一样,在类的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为
class MyClass { constructor { } get prop() { return 'getter' } set prop(value) { console.log('setter' + value) } } let myclass = new MyClass() myclass.prop = 123 // setter123 console.log(myclass.prop) // getter
-
class的静态方法
- 类相当于实例的原型,所以在类中定义的方法,都会被实例继承,如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就成为‘静态方法’, 静态方法中的this指向的时当前的类,而不是实例
- 父类的静态方法,可以被子类继承
class Foo () { static classMethod () { return 'hello' } } Foo.classMethod() // hello var foo = new Foo() // foo.classMethod // 报错 class Bar extends Foo { } Bar.classMethod() // hello
-
class的静态属性和实例属性
- 静态属性指的是class本身的属性,即类名.propName, 而不是定义在实例对象(this)的属性
- 类的实例属性可以用等式,写入类的定义之中
class Foo { myProp = 40 // 即使没this只要在类的定义之中就是实例属性 constructor () { console.log(this.myProp) // 40 } } Foo.prop = 1 // 类的属性 Foo.prop // 1
- 静态属性指的是class本身的属性,即类名.propName, 而不是定义在实例对象(this)的属性