JavaScript面向對象的三大特征
概述
本來打算寫設計模式的,在談論js的設計模式之前先說一下js的面向對象,因為很多設計模式的實現都摻雜著面向對象的思想,所以先做一下前期鋪墊。
js我們都知道是一種動態類型腳本型語言,變量類型無法保證,所以我們可以嘗試調用任意對象的任意方法,不用考慮它原本是否被設計為擁有該方法。
什么是面向對象本文不在論述,接下來說一下面向對象的三大特征在js當中的實現。
封裝
這個特性在設計一個框架時需要認真考慮的。封裝的目的是將信息隱藏,其主要可分為以下幾類
-
數據封裝
在一些靜態類型的語言如java中,本身語法就提供了這些功能。js當中只能依靠變量的作用域來實現封裝的特性,并且只能模擬出public和private兩種特性。
/**
- 利用函數創建的作用域達到數據封裝的目的。
@type {{getName, setName}}
*/
var obj=(function () {
var _name="gcy";
return {
getName:function () {
return _name;
},
setName:function (val) {
_name=val;
}
};
})();
obj._name; //undefined
obj.getName(); //gcy</code></pre>
-
封裝實現
封裝實現就是是對象內部的變化對外界是透明的,不可見。這種做法使對象之間低耦合,便于維護升級,團隊協作開發。
$(selector).each(function(index,element))。就比如這個each函數,我們不用關心內部實現,只要提供的功能正確就行。我們關注的只是接口調用形式。
繼承
繼承在靜態語言中,例如java有關鍵字,雖然在es6中也有extend以及class,但其本質仍實現仍是基于原型機制。
/**
- 簡單的es5原型繼承
- @constructor
*/
var A=function () {
}
A.prototype={name:"gcy"};
var B=function () {
};
B.prototype=new A();
var b=new B();
console.log(b.name);
/**
- e6繼承實現demo
*/
class People{
constructor(name){
this.name=name;
}
getName(){
return this.name;
}
}
class Black extends People{
constructor(name){
super(name);
}
speak(){
return " i am black";
}
}
var peo=new Black("gcy");
console.log(peo.getName()+' says '+peo.speak());</code></pre>
其實有原型繼承方式寫法很多,我認為還是理解原型鏈機制比較重要,關鍵就是理解prototype和__prototype__.
多態
多態其實就是把做的內容和誰去做分開。在java中我們可以通過向上轉型,也就是面向接口編程。因為js是動態語言,多態性本身就有。
下面這個例子就說明了,一個動物能否實現叫聲,只取決于makeSound,不針對某種類型的對象。
/**
* 多態的實現案例
* @param animal
*/
var makeSound=function (animal) {
animal.sound();
}
var Duck=function () {
}
var Dog=function () {
}
Duck.prototype.sound=function () {
console.log("嘎嘎嘎")
}
Dog.prototype.sound=function () {
console.log("旺旺旺")
}
makeSound(new Duck());
makeSound(new Dog());</code></pre>
來自:https://segmentfault.com/a/1190000008321085