2、Es常用語法 箭頭函數、類
1、箭頭函數
什麽是箭頭函數
箭頭函數的語法非常簡單,看一下最簡單的箭頭函數表示法
() => console.log(‘Hello‘)
() => {console.log(‘Hello‘)}
等同於
function(){ console.log(‘hello‘) }
箭頭函數裏的this:
箭頭函數裏的this指向定義時的作用域
普通函數裏的this指向調用者的作用域
箭頭函數不綁定arguments
let arrowfunc = () => console.log(arguments.length) arrowfunc() //output arguments isnot defined
如果此時我們想要獲得函數的參數可以借助擴展運算符“...”
let arrowfunc = (...theArgs) => console.log(theArgs.length) arrowfunc(1,2) //output 2
2、類
js生成實例對象的傳統方式是通過構造函數:
function Point (x, y){ this.x = x; this.y = y; } Point.prototype.toString = function(){ return `( ${this.x} , ${this.y} )` }var p = new Point(1,2); p.toString(); //"(1,2)"
Es6通過class關鍵字定義類
前面不需要加function這個關鍵字,直接將函數定義放進去就行了 ,另外,方法之間不需要逗號分隔;
//定義類 class Point { constructor (x, y) { this.x =x; this.y =y; } toString () { return `( ${this.x}, ${this.y} )`; } toValue () {return this.x+this.y; } } var p = new Point(1,2); p.toString(); //"(1,2)" p.toValue(); //3
constructor方法
constructor方法是是類的默認方法,通過new命令生成對象實例時,自動調用該方法,一個類必須有constructor方法,如果沒有顯示定義,一個空的constructor方法會被默認添加:
1 class Point{ 2 } 3 4 //等同於 5 class Point { 6 constructor () { } 7 } 8 //定義了一個空的類Point,JavaScript 引擎會自動為它添加一個空的constructor方法。
constructor方法默認返回實例對象(即this),完全可以指定返回另外一個對象;
class Person { constructor () { return Object.create(null); } } new Person() instanceof Person //false //實例 instanceof 構造函數 用來判斷實例是否是構造函數的實例
構造函數的prototype屬性,在ES6的類上繼續存在,實際上,類的所有方法都定義在類的prototype屬性上面;
//定義類 class Point { constructor (x, y) { this.x =x; this.y =y; } toString () { return `(${this.x},${this.y})`; } } var point = new Point(1,2); point.toString();//(1,2) point.hasOwnProperty("x"); //true point.hasOwnProperty("y"); //true point.hasOwnProperty("toString");//fasle point.__proto__.hasOwnProperty("toString");//true
clss表達式
和函數一樣,類也可以使用表達式的形式定義:
const MyClass = class Me{ getClassName () { return Me.name ; } }; let inst = new MyClass(); inst .getClassName(); //"Me" Me.name //ReferenceError :Me is not defined
Me只有在Class內部有定義;
如果類的內部沒有用到的話,可以省略Me,可以改寫成:
const MyClass = class { getClassName () { return ; } }
采用Class表達式,可以寫出立即執行Class
let person = new class { constructor (name) { this.name = name ; } sayName() { console.log(this.name); } }("張三"); person.sayName(); //"張三"
class不存在變量提升
new Foo();//ReferenceError class Foo();
this的指向
類的方法內部如果含有this,他默認指向類的實例,但是,必須非常小心,一旦單獨使用該方法,可能會報錯;
class Logger { printName(name = ‘there‘) { this.print(`Hello ${name}`); } print(text) { console.log(text); } } const logger = new Logger(); const { printName } = logger; printName(); // TypeError: Cannot read property ‘print‘ of undefined
Class 的取值函數(getter)和存值函數(setter)
與 ES5 一樣,在“類”的內部可以使用get和set關鍵字,對某個屬性設置存值函數和取值函數,攔截該屬性的存取行為
class MyClass { constructor() { // ... } get prop() { return ‘getter‘; } set prop(value) { console.log(‘setter: ‘+value); } } let inst = new MyClass(); inst.prop = 123; // setter: 123 inst.prop // ‘getter‘
prop屬性有對應的存值函數和取值函數,因此賦值和讀取行為都被自定義了。
Class 的靜態方法
類相當於實例的原型,所有在類中定義的方法,都會被實例繼承。如果在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承,而是直接通過類來調用,這就稱為“靜態方法”
class Foo { static classMethod() { return ‘hello‘; } } Foo.classMethod() // ‘hello‘ var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function
Foo類的classMethod方法前有static關鍵字,表明該方法是一個靜態方法,可以直接在Foo類上調用(Foo.classMethod()),而不是在Foo類的實例上調用。如果在實例上調用靜態方法,會拋出一個錯誤,表示不存在該方法。
註意,如果靜態方法包含this關鍵字,這個this指的是類,而不是實例。
class Foo { static bar () { this.baz(); } static baz () { console.log(‘hello‘); } baz () { console.log(‘world‘); } } Foo.bar() // hello
靜態方法bar調用了this.baz,這裏的this指的是Foo類,而不是Foo的實例,等同於調用Foo.baz。另外,從這個例子還可以看出,靜態方法可以與非靜態方法重名。
父類的靜態方法,可以被子類繼承。
class Foo { static classMethod() { return ‘hello‘; } } class Bar extends Foo { } Bar.classMethod() // ‘hello
靜態方法也是可以從super對象上調用的。
Class 的靜態屬性和實例屬性
靜態屬性指的是 Class 本身的屬性,即Class.propName,而不是定義在實例對象(this)上的屬性。
class Foo { } Foo.prop = 1; Foo.prop // 1 //Foo類定義了一個靜態屬性prop,只有這種寫法可行,因為 ES6 明確規定,Class 內部只有靜態方法,沒有靜態屬性。
(1)類的實例屬性
類的實例屬性可以用等式,寫入類的定義之中
class MyClass { myProp = 42; constructor() { console.log(this.myProp); // 42 } } //myProp就是MyClass的實例屬性。在MyClass的實例上,可以讀取這個屬性。
2、Es常用語法 箭頭函數、類