前言
面向對象語言的基本特征:封裝,繼承,多態 。 這是我們在學Java的時候,首先映入眼簾的一句話 。封裝 - 顧名思義就是將一些東西(屬性,方法)藏起來 , 不讓外部調用的人知道 , 防止出現使用不當 。 繼承 - 萬事萬物皆為天地所化 , 同出一門而變化萬千 , 既有相同之處又有差異之所 。繼承就是將共有的特征特質向下傳遞 , 父傳子,子傳孫 , 孫又傳孫 , 子子孫孫無窮盡也 。多態 - 萬物終有始焉 , 而好事者歸為類 , 譬如:鳥類 , 人類 , 然,多態始于繼承 , 子繼承有父之功 , 而可完成父之功也 。
在上篇文章中 , 我們大致了解了JavaScript基于引用的面向對象特征 , 但終歸寫起來比較麻煩 , 在ES6標準中 , 已經可以使用class
作為類的關鍵字了 , 有了常規的面向的的寫法了 , 但內部實現原理差不多 , 只是添加了class
及一些面向對象的語法糖 。使用的時候 , 需要考慮兼容性。
ES6面向對象
ECMAScript是一種由Ecma國際通過ECMA-262標準化的腳本程序設計語言。這種語言在萬維網上應用廣泛,它往往被稱為JavaScript或JScript,但實際上后兩者是ECMA-262標準的實現和擴展。 -- 百度百科
基于原型的面向對象
// 基于原型 , 創建一個Person類
function Person() {
// 類的屬性
Person.prototype.name = "zeno";
Person.prototype.age = 20;
Person.prototype.job = "Software Engineer";
// 類的方法
Person.prototype.sayHello = function(){
alert("Hello "+this.name);
};
}
// 創建Person對象
var person = new Person();
alert(person.name); // out : zeno
person.sayHello(); // out : Hello zeno
基于原型的面向對象 , 寫法上比較繁瑣 , 需要使用原型對象屬性 。
ES6 對象寫法
class Person {
constructor() {
var name ;
}
doSomthing() {
console.log('es6面向對象');
}
}
var p = new Person();
p.doSomthing(); // out : es6面向對象
ES6標準的面向對象語法 ,比較像java的寫法 , 但又有些不同 , JavaScript中不能定義類屬性 。
嘗試類屬性
class Person {
var name ;
} // out : es6.html:29 Uncaught SyntaxError: Unexpected identifier
在JavaScript中不支持這種寫法。
繼承 - extends
可以看出和Java的語法有點相像了 , 不過這種寫法好像很多語言都實現了 , 例如PHP
// 父類
class Person {
constructor() {
this.name = 'zeno';
}
doSomthing() {
console.log('es6面向對象');
}
}
// 子類
class Human extends Person {
constructor() {
super();
this.job = 'software enginner' ;
}
}
var h = new Human();
console.log(h.name); // zeno
console.log(h.job); // software enginner
console.log(h.doSomthing()); // 會調用兩次 ,第一次es6面向對象 , 第二次undefined
調用console.log(h.doSomthing());
會調用兩次 , 初步估計是兩個類,各實例化了一次 , 每個對象調用一次doSomthing()
, 父類輸出 , 子類因沒有這個方法 , 而產生了undefined
。但我在子類實現了doSomthing()
方法 , 結果還是執行了兩次 , 這讓我不明就里 , 暫且擱置 , 希望知道的有心人士解惑之 。
多態
JavaScript天生支持多態 , 因為JavaScript是動態語言,沒有類型的向上向下轉性 , 方便了很多 。
封裝
JavaScript在ES6中貌似支持封裝 , 但實驗了一下 , 并不可以 ,沒有語法上的支持 , 就目前來看 , 這是JavaScript最弱的一部分了 。
不可行的封裝
class Dog {
constructor() {
this._name = 'lily';
this.age = 10 ;
}
getDogName() {
return this._name;
}
get Age() {
return this.age ;
}
}
var d = new Dog();
console.log(d._name); // out : lily 可以訪問到
JavaScript ES6中 , 默認以下劃線開頭的屬性為私有屬性或方法 , 然而并沒有什么卵用 , 一樣可以訪問 。
結語
JavaScript在不斷的發展 , 尤其這幾年 , 發展尤其迅速 , 各種庫 , 如雨后春筍般迸發 , 并應用于各個行業和領域 ,并一度向全棧發展 。