JavaScript面向物件程式設計-封裝
前言
面向物件程式設計是將需求抽象成一個物件,針對物件分析其特徵(屬性)和動作(方法)。這個物件我們稱之為類。面向物件程式設計思想其中一個特點就是封裝,就是把需要的功能放在一個物件裡。但是JavaScript這種解釋性的弱型別語言沒有經典強型別語言中通過關鍵字class來實現類的封裝,JavaScript都是通過一些特性模仿實現的,這也讓JavaScript有更高的靈活性。
封裝
為類新增屬性和方法的兩種方式
- 在函式(類)的內部通過this新增屬性和方法
//建立類,通過this實現對類新增屬性和方法 var Book = function (id, bookname, price) { this.id = id; this.bookname = bookname; this.price = price; }
- 通過在類的原型上新增屬性和方法
1)為原型物件屬性賦值
Book.prototype.display = function () {
}
2)將一個物件賦值給類的原型物件
Book.prototype = {
display :function () {
}
}
這樣就將需要的方法和屬性封裝在抽象的Book類中,當使用功能方法時,不能直接使用Book類,而需要new關鍵字來例項化(建立)新的物件。注意:通過this新增的屬性和方法是在當前物件上新增的,而通過JavaScript是一種基於原型prototype的語言,所以每建立一個物件時,都有一個原型prototype用於指向其繼承的屬性、方法。這樣通過prototype繼承的方法並不是物件自身的。所以每次通過類建立一個新物件時,this指向的屬性和方法都會得到相應的建立,但是通過prototype繼承的屬性和方法是每個物件通過prototype訪問到,這些屬性和方法不會再次建立。
通過this建立的屬性是公有屬性,通過this建立的方法是特權方法,在建立物件時呼叫特權方法可以看做是類的構造器。通過new關鍵字建立新物件時,由於類外面通過點語法新增的屬性和方法沒有執行到,所以新建立的物件中無法獲取到,而prototype建立的屬性或方法可以訪問到,所以prototype物件中的屬性和方法稱為共有屬性和方法。如下:
var Book = function (id, name, price) { } Book.isChinese = true; Book.prototype = { isJsBook : false, display :function () {} } var b = new Book(11,'ava', 30); console.log(b.isJsBook); //false console.log(b.id); // 11 console.log(b.idChinese); //undefined console.log(Book.isChinese);// true
閉包實現
閉包是有權訪問另一個函式作用域中變數的函式,即在一個函式內部建立另一個函式。將閉包作為建立物件的建構函式。
//利用閉包實現
var Book =(function () {
var bookNum = 0;
function checkBook(name) {}
function book(newId,newName,newPrice) {
var name,price;
function checkId() {}
this.getName = function(){};
this.getPrice = function () {};
this.setName = function () {};
this.setPrice = function () {};
this.id = newId;
this.copy = function () {};
bookNum++
if(bookNum>100){
throw new Error('100本書');
}
this.setName(name);
this.setName(price);
}
_book.prototype = {
isJsBook :false,
display:function () {}
};
return _book;
})();
由於在建立物件上這種寫法容易忘記使用new而犯錯誤,所以可以使用安全模式建立物件,也就是在建立物件過程中用instanceof判斷this是否是當前這個物件。
if(this instanceof Book){
...
}else{
return new Book()
}