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)的屬性