摘要:使用除關(guān)鍵字之外的方式調(diào)用構(gòu)造函數(shù)會導(dǎo)致程序拋出錯誤。在類中修改類名會導(dǎo)致程序報錯。與之等價的聲明必須通過關(guān)鍵字調(diào)用構(gòu)造函數(shù)不可使用關(guān)鍵字調(diào)用構(gòu)造函數(shù)類表達式類表達式可以是被命名的或匿名的。類也是中的一等公民。
概述
class (類)作為對象的模板被引入,可以通過 class 關(guān)鍵字定義類。類簡要說明
類的本質(zhì)是function,是基本原型繼承的語法糖。所以,JS中繼承的模型是不會被改變的。
類既然是函數(shù),那與函數(shù)有何不同呢?我們?yōu)槭裁匆褂妙惸兀?br>有時間,先看一下MDN od
函數(shù)聲明可以被提升,而類聲明與let/const 聲明類似,不能被提升,也就是在真正執(zhí)行聲明之前,它們會一直存在于臨時死區(qū)中。
類聲明中的所有代碼將自動運行在嚴格模式下,而且無法強行讓代碼脫離嚴格模式。
類中的所有方法,都是不可枚舉的。而普通自定義類型中,必須通過Object.defineProperty()方法來指定某方法不可枚舉。
每個類都有一個[[Construct]]的內(nèi)部方法,通過關(guān)鍵字new調(diào)用那些不含[[Construct]]的方法會導(dǎo)致程序拋出錯誤。
使用除關(guān)鍵字new之外的方式調(diào)用構(gòu)造函數(shù)會導(dǎo)致程序拋出錯誤。
在類中修改類名會導(dǎo)致程序報錯。
類聲明首先class關(guān)鍵字,然后是類的名字,其它部分的語法,類似于對象字面量方法的簡寫形式,但不需要在各元素之間使用逗號分隔。
class HelloClass { constructor(greeting) { this.greeting = greeting; } sayGreeting(){ console.log(this.greeting); } } let hello = new HelloClass("Hello"); hello.sayGreeting(); // Hello console.log(hello instanceof HelloClass); // true console.log(hello instanceof Object); // true console.log(typeof HelloClass); // function console.log(typeof HelloClass.prototype.sayGreeting); // function
分析:
constructor為保留方法名,是用來構(gòu)建對象的,不可用作其它用途。
函數(shù)定義之前,不需要添加function關(guān)鍵字。
類的屬性不可被賦予新值,HelloClass.prototype是一個只可讀類屬性。
與之等價的ES5聲明
let HelloClass = (function(){ "use strict"; const HelloClass = function(greeting) { if (typeof new.target === "undefined") { throw new Error("必須通過關(guān)鍵字new調(diào)用構(gòu)造函數(shù)"); } this.greeting = greeting; Object.defineProperty(HelloClass.prototype, "sayGreeting", { value: function() { if (typeof new.target !== "undefined") { throw new Error("不可使用關(guān)鍵字new調(diào)用構(gòu)造函數(shù)"); } console.log(this.greeting); }, enumerable: false, writable: true, configurable: true }); } return HelloClass; }()); let hello = new HelloClass("Hello"); hello.sayGreeting(); console.log(hello instanceof HelloClass); console.log(hello instanceof Object); console.log(typeof HelloClass); console.log(typeof HelloClass.prototype.sayGreeting);類表達式
類表達式可以是被命名的或匿名的。賦予一個命名類表達式的名稱是類的主體的本地名稱。和function的表達式類似,但不會像函數(shù)聲名或和函數(shù)表達式一樣被提升。
/* 匿名類 */ let Rectangle = class { constructor(height, width) { this.height = height; this.width = width; } }; console.log(typeof Rectangle); // function
/* 命名的類 */ let Rectangle = class Rectangle1 { constructor(height, width) { this.height = height; this.width = width; } }; console.log(typeof Rectange); // function console.log(typeof Rectange1); // undefined
在JS中,函數(shù)為一等“公民”,可以傳入函數(shù),也可以從函數(shù)中返回,還可以賦值給變量的值。類也是JS中的一等公民。
訪問器- getter - setter
class Rectangle { // constructor constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea() } // Method calcArea() { return this.height * this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100可計算成員
const methodName = "sayGreeting"; class HelloClass { constructor(greeting) { this.greeting = greeting; } [methodName]() { console.log(this.greeting); } } let hello = new HelloClass("Hello"); hello.sayGreeting(); // Hello hello[methodName](); // Hello
可計算訪問器屬性。
const propertyName = "greeting"; class HelloClass { constructor() { } get [propertyName]() { return this.greetingStr; } set [propertyName](value) { this.greetingStr = value; } } let hello = new HelloClass(); hello.greeting = "Hello"; console.log(hello.greeting);生成器方法
class NormClass { *createIterator() { yield 1; yield 2; yield 3; } } let instance = new NormClass(); let iterator = instance.createIterator(); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }
為類定義默認迭代器。
class Collection { constructor() { this.items = []; } *[Symbol.iterator]() { yield *this.items.values(); } } var coll = new Collection(); coll.items.push(1); coll.items.push(2); coll.items.push(3); for (let i of coll) { console.log(i); } // 1 // 2 // 3靜態(tài)成員
class Animal { speak() { return this; } static eat() { return this; } } let obj = new Animal(); console.log(obj.speak()); // Animal {} let speak = obj.speak; console.log(speak()); // undefined console.log(Animal.eat()); // class Animal let eat = Animal.eat; console.log(eat()); // undefined
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/105803.html
摘要:一自定義收集器陳楊將集合轉(zhuǎn)換為集合存放相同元素二自定義收集器陳楊將學生對象按照存放從中間容器數(shù)據(jù)類型轉(zhuǎn)換為結(jié)果類型數(shù)據(jù)類型一致若不一致拋出類型轉(zhuǎn)換異常對中間容器數(shù)據(jù)結(jié)果類型進行強制類型轉(zhuǎn)換多個線程同時操作同一個容器并行多線 一、自定義SetCustomCollector收集器 package com.java.design.Stream.CustomCollector; impor...
摘要:寫這個文章其實主要是因為剛有個童鞋問了個問題正寫的帶勁安利的實現(xiàn)方式,結(jié)果還沒寫完無意發(fā)現(xiàn)問題被關(guān)閉了哎都寫了一半了又不想放棄,就干脆寫成文章問題主要就是把集合里的數(shù)據(jù)按照一定大小順序平均分成若干組的問題,看起來挺簡單的,不過我開始看到就想 寫這個文章其實主要是因為剛有個童鞋問了個問題https://segmentfault.com/q/10...正寫的帶勁安利Java8的實現(xiàn)方式,結(jié)...
摘要:使用流收集數(shù)據(jù)分區(qū)分區(qū)是分組的特殊情況由一個謂詞返回一個布爾值的函數(shù)作為分類函數(shù),它稱分區(qū)函數(shù)。這種情況下,累加器對象將會直接用作歸約過程的最終結(jié)果。這也意味著,將累加器不加檢查地轉(zhuǎn)換為結(jié)果是安全的。 使用流收集數(shù)據(jù) 分區(qū) 分區(qū)是分組的特殊情況:由一個謂詞(返回一個布爾值的函數(shù))作為分類函數(shù),它稱分區(qū)函數(shù)。分區(qū)函數(shù)返回一個布爾值,這意味著得到的分組 Map 的鍵類型是 Boolean ...
摘要:構(gòu)造函數(shù)繼承在子類的構(gòu)造函數(shù)中,通過或的形式,調(diào)用父類構(gòu)造函數(shù),以實現(xiàn)繼承。所以,其實單獨使用原型鏈繼承或者借用構(gòu)造函數(shù)繼承都有自己很大的缺點,最好的辦法是,將兩者結(jié)合一起使用,發(fā)揮各自的優(yōu)勢。使指向自己而不是指向構(gòu)造函數(shù) 原型鏈繼承 子類的所有實例都共享著原型上的所有屬性和方法。通過子類實例,可以訪問原型上的屬性,但是,不能重寫原型上的屬性。 //定義一個學生類 function S...
摘要:一收集器接口陳楊收集器接口匯聚操作的元素類型即流中元素類型匯聚操作的可變累積類型匯聚操作的結(jié)果類型接口一種可變匯聚操作將輸入元素累積到可變結(jié)果容器中在處理完所有輸入元素后可以選擇將累積的結(jié)果轉(zhuǎn)換為最終表示可選操作歸約操作 一、Stream收集器 Collector接口 package com.java.design.java8.Stream; import com.java.desi...
閱讀 2748·2021-11-18 10:02
閱讀 3479·2021-09-28 09:35
閱讀 2720·2021-09-22 15:12
閱讀 813·2021-09-22 15:08
閱讀 3362·2021-09-07 09:58
閱讀 3533·2021-08-23 09:42
閱讀 793·2019-08-30 12:53
閱讀 2149·2019-08-29 13:51