本文涉及的主題雖然很基礎,在許多人看來屬於小伎倆,但在JavaScript基礎知識中屬於一個綜合性的話題。這裡會涉及到物件屬性的封裝、原型、建構子、閉包以及立即執行表達式等知識。
公有方法
公有方法就是能被外部存取並呼叫的方法。
// 在对象中 var Restaurant = { name: 'McDonald', // 公有方法 getName: function() { return this.name; } } // 在构造函数中 function Person(name, age) { this.name = name; this.age = age; // 公有方法 this.getName = function() { return this.name; } } // 在原型中 Person.prototype.getAge = function() { return this.age; }
私有方法和特權方法
這兩個方法一般放在一起討論,原因在於我們定義的特權方法是指有權訪問內部私有屬性和私有方法的公有方法,而私有方法是指外部不可見且不可訪問的方法。
通常定義一個物件的方式有二種,一是使用Object實例化或物件表達式,二是使用建構子。同樣在不同的方式下面定義私有方法和特權方法的形式也不相同。
在物件中
這裡我們透過Object物件表達式來建立一個物件並加入一些屬性和方法,然後直接採用靜態的方式來呼叫。物件的私有資料放置在一個匿名函數立即執行表達式(IIFE)中。這意味著這個函數只存在於被呼叫的瞬間,一旦執行後就立即被銷毀了。
在物件中建立私有資料的方式在物件的模式(指建立物件的模式)中稱為模組模式,它的基本格式如下:
var yourObject = (function() { // 私有属性和方法 return { // 公有方法和属性 } }) ();
在模組模式中,傳回的物件字面量中只包含可以公開的屬性和方法。
var Restaurant = (function() { // 私有属性 var _total = 10; // 私有方法 var _buyFood = function() { _total--; }; var _getTotal = function() { return _total; } return { name: 'McDonald', getTotal: _getTotal, buy: _buyFood } }) (); Restaurant.buy(); console.log(Restaurant.name); // 'McDonald' console.log(Restaurant.getTotal()); // 9
注意我們使用了閉包的方式來間接使用內部私有變量,同時對餐廳(Restaurant)名稱(name)進行了初始化。
在建構子
在上面介紹的模組模式創建私有方法時,公有方法和特權方法並沒有什麼本質上的區別,原因在於這個概念是來自於使用構造函數創建私有資料的時候定義出來的。
在建構函式中定義私有屬性和方法很方便,我們不需要使用閉包,可以在呼叫的時候初始化資料。
function Restaurant(name) { // 私有属性 var _total = 10; // 公有属性 this.name = name; // 私有方法 function _buyFood() { _total--; } // 特权方法 this.buy = function() { _buyFood(); } this.getTotal = function() { return _total; } } // 公有方法, 注意这里不能访问私有成员_total Restaurant.prototype.getName = function() { console.log(_total); // Uncaught ReferenceError: _total is not defined return this.name; } var McDonald = new Restaurant('McDonald'); console.log(McDonald.getName()); // 'McDonald' McDonald.buy(); console.log(McDonald.getTotal()); // 9
合而為一,更有彈性的方式
使用模組模式我們可以多次調用,每次執行完後都會被銷毀掉。使用建構函數方式可以傳入一些初始化的數據,但在公有方法中無法存取到私有成員屬性,如果有很多公有方法需要存取私有數據,我們全部用特權方法來寫,最後會給每個實例帶去很多沒有必要的方法。因此,將兩者結合在一起可以長短互補,結合方式也很簡單
var Restaurant = (function() { // 私有属性 var _total = 10; // 私有方法 function _buyFood() { _total--; } // 构造函数 function restaurant(name) { this.name = name; this.getTotal = function() { return _total; } } restaurant.prototype.buy = function() { console.log(_total); // 10 _buyFood(); } restaurant.prototype.getName = function() { return this.name; } return restaurant; }) (); var McDonald = new Restaurant('McDonald'); console.log(McDonald.getName()); // 'McDonald' McDonald.buy(); console.log(McDonald.getTotal()); // 9
以上就是本文的全部內容,小編只是總結了其中一小部分,還有許多未提及到的知識點,大家可以自己摸索研究,希望本文可以對初學者有所幫助。