摘要:使用除關鍵字之外的方式調用構造函數會導致程序拋出錯誤。在類中修改類名會導致程序報錯。與之等價的聲明必須通過關鍵字調用構造函數不可使用關鍵字調用構造函數類表達式類表達式可以是被命名的或匿名的。類也是中的一等公民。
概述
class (類)作為對象的模板被引入,可以通過 class 關鍵字定義類。類簡要說明
類的本質是function,是基本原型繼承的語法糖。所以,JS中繼承的模型是不會被改變的。
類既然是函數,那與函數有何不同呢?我們為什么要使用類呢?
有時間,先看一下MDN od
函數聲明可以被提升,而類聲明與let/const 聲明類似,不能被提升,也就是在真正執行聲明之前,它們會一直存在于臨時死區中。
類聲明中的所有代碼將自動運行在嚴格模式下,而且無法強行讓代碼脫離嚴格模式。
類中的所有方法,都是不可枚舉的。而普通自定義類型中,必須通過Object.defineProperty()方法來指定某方法不可枚舉。
每個類都有一個[[Construct]]的內部方法,通過關鍵字new調用那些不含[[Construct]]的方法會導致程序拋出錯誤。
使用除關鍵字new之外的方式調用構造函數會導致程序拋出錯誤。
在類中修改類名會導致程序報錯。
類聲明首先class關鍵字,然后是類的名字,其它部分的語法,類似于對象字面量方法的簡寫形式,但不需要在各元素之間使用逗號分隔。
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為保留方法名,是用來構建對象的,不可用作其它用途。
函數定義之前,不需要添加function關鍵字。
類的屬性不可被賦予新值,HelloClass.prototype是一個只可讀類屬性。
與之等價的ES5聲明
let HelloClass = (function(){ "use strict"; const HelloClass = function(greeting) { if (typeof new.target === "undefined") { throw new Error("必須通過關鍵字new調用構造函數"); } this.greeting = greeting; Object.defineProperty(HelloClass.prototype, "sayGreeting", { value: function() { if (typeof new.target !== "undefined") { throw new Error("不可使用關鍵字new調用構造函數"); } 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的表達式類似,但不會像函數聲名或和函數表達式一樣被提升。
/* 匿名類 */ 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中,函數為一等“公民”,可以傳入函數,也可以從函數中返回,還可以賦值給變量的值。類也是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靜態成員
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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105803.html
摘要:一自定義收集器陳楊將集合轉換為集合存放相同元素二自定義收集器陳楊將學生對象按照存放從中間容器數據類型轉換為結果類型數據類型一致若不一致拋出類型轉換異常對中間容器數據結果類型進行強制類型轉換多個線程同時操作同一個容器并行多線 一、自定義SetCustomCollector收集器 package com.java.design.Stream.CustomCollector; impor...
摘要:寫這個文章其實主要是因為剛有個童鞋問了個問題正寫的帶勁安利的實現方式,結果還沒寫完無意發現問題被關閉了哎都寫了一半了又不想放棄,就干脆寫成文章問題主要就是把集合里的數據按照一定大小順序平均分成若干組的問題,看起來挺簡單的,不過我開始看到就想 寫這個文章其實主要是因為剛有個童鞋問了個問題https://segmentfault.com/q/10...正寫的帶勁安利Java8的實現方式,結...
摘要:使用流收集數據分區分區是分組的特殊情況由一個謂詞返回一個布爾值的函數作為分類函數,它稱分區函數。這種情況下,累加器對象將會直接用作歸約過程的最終結果。這也意味著,將累加器不加檢查地轉換為結果是安全的。 使用流收集數據 分區 分區是分組的特殊情況:由一個謂詞(返回一個布爾值的函數)作為分類函數,它稱分區函數。分區函數返回一個布爾值,這意味著得到的分組 Map 的鍵類型是 Boolean ...
摘要:構造函數繼承在子類的構造函數中,通過或的形式,調用父類構造函數,以實現繼承。所以,其實單獨使用原型鏈繼承或者借用構造函數繼承都有自己很大的缺點,最好的辦法是,將兩者結合一起使用,發揮各自的優勢。使指向自己而不是指向構造函數 原型鏈繼承 子類的所有實例都共享著原型上的所有屬性和方法。通過子類實例,可以訪問原型上的屬性,但是,不能重寫原型上的屬性。 //定義一個學生類 function S...
摘要:一收集器接口陳楊收集器接口匯聚操作的元素類型即流中元素類型匯聚操作的可變累積類型匯聚操作的結果類型接口一種可變匯聚操作將輸入元素累積到可變結果容器中在處理完所有輸入元素后可以選擇將累積的結果轉換為最終表示可選操作歸約操作 一、Stream收集器 Collector接口 package com.java.design.java8.Stream; import com.java.desi...
閱讀 2672·2021-11-18 10:02
閱讀 3402·2021-09-28 09:35
閱讀 2586·2021-09-22 15:12
閱讀 742·2021-09-22 15:08
閱讀 3071·2021-09-07 09:58
閱讀 3464·2021-08-23 09:42
閱讀 725·2019-08-30 12:53
閱讀 2072·2019-08-29 13:51