首頁 web前端 js教程 怎樣編寫可維護的物件導向 JavaScript 程式碼

怎樣編寫可維護的物件導向 JavaScript 程式碼

Nov 29, 2016 am 10:08 AM
javascript 物件導向

能夠寫出可維護的物件導向JavaScript程式碼不僅可以節省金錢,還能讓你很受歡迎。不相信?有可能你自己或其他什麼人有一天會回來重複使用你的程式碼。如果能盡量讓這個經歷不那麼痛苦,就可以省下不少時間。地球人都知道,時間就是金錢。同樣的,你也會因為幫某人省去了頭痛的過程而獲得他的偏好。但是,在開始探索如何編寫可維護的物件導向JavaScript程式碼之前,我們先來快速看看什麼是物件導向。如果已經了解物件導向的概念了,就可以直接跳過下一節。


什麼是物件導向?


物件導向程式設計主要透過程式碼代表現實世界中的實質物件。要建立對象,首先需要寫一個「類別」來定義。 類幾乎可以代表所有的東西:帳戶,員工,導航菜單,汽車,植物,廣告,飲料,等等。而每次要創建物件的時候,就從類別實例化一個物件。換句話說,就是創建類別的實例做為物件。事實上,通常處理一個以上的同類事物時就會使用到物件。另外,只需要簡單的函數式程式就可以做的很好。對象實質上是資料的容器。因此在一個employee物件中,你可能要儲存員工號,姓名,入職日期,職稱,工資,資歷,等等。


物件也包含處理資料的函數(也稱為「方法」)。方法被用作媒介來確保資料的完整性,以及在儲存之前對資料進行轉換。例如,方法可以接收任意格式的日期然後在儲存之前將其轉換成標準化格式。最後,類別還可以繼承其他的類別。繼承可以讓你在不同類別中重複使用相同程式碼。例如,銀行帳戶和音像店帳戶都可以繼承一個基本的帳戶類,裡麵包括個人信息,開戶日期,分部信息,等等。然後每個都可以定義自己的交易或借款處理等資料結構和方法。


警告:JavaScript物件導向是不一樣的


在上一節中,概述了經典的物件導向程式設計的基本知識。說經典是因為JavaScript並不遵守這些規則。相反地​​,JavaScript的類別是寫成函數的樣子,而繼承則是透過原型實現的。原型繼承基本上意味著使用原型屬性來實現物件的繼承,而不是從類別繼承類別。


物件的實例化


以下是JavaScript中物件實例化的例子:

// 定义Employee类
  function Employee(num, fname, lname) {
    this.getFullName = function () {
  return fname + " " + lname;
  }
  };
// 实例化Employee对象
  var john = new Employee("4815162342", "John", "Doe");
  alert("The employee's full name is " + john.getFullName());
登入後複製

在這裡,有三個重點需要注意:

個字母要大寫。這表明該函數的目的是被實例化而不是像一般函數一樣被呼叫。

2 在實例化的時候使用了new操作符。如果省略掉new而只呼叫函數則會產生很多問題。

3 因為getFullName指定給this操作符了,所以是公共可用的,但是fname和lname則不是。由Employee函數產生的閉包給了getFullName到fname和lname的入口,但同時對於其他類別仍然是私有的。

原型繼承

下面是JavaScript中原型繼承的例子:

// 定义Human类
function Human() {
this.setName = function (fname, lname) {
this.fname = fname;
this.lname = lname;
}
this.getFullName = function () {
return this.fname + " " + this.lname;
}
}
// 定义Employee类
function Employee(num) {
this.getNum = function () {
return num;
}
};
//让Employee继承Human类
Employee.prototype = new Human();
// 实例化Employee对象
var john = new Employee("4815162342");
john.setName("John", "Doe");
alert(john.getFullName() + "'s employee number is " + john.getNum());
登入後複製

這一次,創建的Human類,包含人類的一切共有屬性——我也將fname和lname放進去了這次,創建的Human類,因為不只是員工才有名字,所有人都有名字。然後將Human物件賦值給它的prototype屬性。

透過繼承實現程式碼重用

在前面的例子中,原來的Employee類別被分解成兩個部分。所有的人類通用屬性被移到了Human類別中,然後讓Employee繼承Human。這樣的話,Human裡面的屬性就可以被其他的物件使用,例如Student(學生),Client(顧客),Citizen(公民),Visitor(遊客),等等。現在你可能注意到了,這是分割和重複使用程式碼很好的方式。處理Human物件時,只需要繼承Human來使用已存在的屬性,而不需要對每種不同的物件都重新一一建立。除此之外,如果要新增一個「中間名字」的屬性,只需要加一次,那些繼承了 Human 類別的就可以立刻使用了。反而言之,如果我們只是想要給一個物件加上「中間名字」的屬性,我們就直接加在那個物件裡面,而不需要在Human 類別裡面加。

1. Public(公有的)和Private(私有的)

接下來的主題,我想談談類別中的公有和私有變數。根據物件中處理資料的方式不同,資料會被處理為私有的或公有的。私有屬性並不一定意味著其他人無法存取。可能只是某個方法需要用到。

只讀

有時,你只是想要在創建對象的時候能有一個值。一旦創建,就不想要其他人再改變這個值。為了做到這一點,可以創建一個私有變量,在實例化的時候給它賦值。

function Animal(type) {
var data = [];
data['type'] = type;
this.getType = function () {
return data['type'];
}
}
var fluffy = new Animal('dog');
fluffy.getType();
// 返回 'dog'
登入後複製

在这个例子中,Animal类中创建了一个本地数组data。当 Animal对象被实例化时,传递了一个type的值并将该值放置在data数组中。因为它是私有的,所以该值无法被覆盖(Animal函数定义了它的范围)。一旦对象被实例化了,读取type值的唯一方式是调用getType方法。因为getType是在Animal中定义的,因此凭借Animal产生的闭包,getType可以进到data中。这样的话,虽可以读到对象的类型却无法改变。


有一点非常重要,就是当对象被继承时,“只读”技术就无法运用。在执行继承后,每个实例化的对象都会共享那些只读变量并覆盖其值。最简单的解决办法是将类中的只读变量转换成公共变量。但是你必须保持它们是私有的,你可以使用Philippe在评论中提到的技术。


Public(公有)


当然也有些时候你想要任意读写某个属性的值。要实现这一点,需要使用this操作符。

function Animal() {
this.mood = '';
}
var fluffy = new Animal();
fluffy.mood = 'happy';
fluffy.mood;
// 返回 'happy'
登入後複製


这次Animal类公开了一个叫mood的属性,可以被随意读写。同样地,你还可以将函数指定给公有的属性,例如之前例子中的getType函数。只是要注意不要给getType赋值,不然的话你会毁了它的。


完全私有


最后,可能你发现你需要一个完全私有化的本地变量。这样的话,你可以使用与第一个例子中一样的模式而不需要创建公有方法。

function Animal() {
var secret = "You'll never know!"
}
var fluffy = new Animal();
登入後複製


2. 写灵活的API


既然我们已经谈到类的创建,为了保持与产品需求变化同步,我们需要保持代码不过时。如果你已经做过某些项目或者是长期维护过某个产品,那么你就应该知道需求是变化的。这是一个不争的事实。如果你不是这么想的话,那么你的代码在还没有写之前就将注定荒废。可能你突然就需要将选项卡中的内容弄成动画形式,或是需要通过Ajax调用来获取数据。尽管准确预测未来是不大可能,但是却完全可以将代码写灵活以备将来不时之需。


Saner参数列表


在设计参数列表的时候可以让代码有前瞻性。参数列表是让别人实现你代码的主要接触点,如果没有设计好的话,是会很有问题的。你应该避免下面这样的参数列表:

function Person(employeeId, fname, lname, tel, fax, email, email2, dob) {
};
登入後複製


这个类十分脆弱。如果在你发布代码后想要添加一个中间名参数,因为顺序问题,你不得不在列表的最后往上加。这让工作变得尴尬。如果你没有为每个参数赋值的话,将会十分困难。例如:

var ara = new Person(1234, "Ara", "Pehlivanian", "514-555-1234", null, null, null, "1976-05-17");
登入後複製

操作参数列表更整洁也更灵活的方式是使用这个模式:

function Person(employeeId, data) {
};
登入後複製

有第一个参数因为这是必需的。剩下的就混在对象的里面,这样才可以灵活运用。

var ara = new Person(1234, {
fname: "Ara",
lname: "Pehlivanian",
tel: "514-555-1234",
dob: "1976-05-17"
});
登入後複製

这个模式的漂亮之处在于它即方便阅读又高度灵活。注意到fax, email和email2完全被忽略了。不仅如此,对象是没有特定顺序的,因此哪里方便就在哪里添加一个中间名参数是非常容易的:

var ara = new Person(1234, {
fname: "Ara",
mname: "Chris",
lname: "Pehlivanian",
tel: "514-555-1234",
dob: "1976-05-17"
});
登入後複製

类里面的代码不重要,因为里面的值可以通过索引来访问:

function Person(employeeId, data) {
this.fname = data['fname'];
};
登入後複製

如果data['fname'] 返回一个值,那么他就被设定好了。否则的话,没被设定好,也没有什么损失。

让代码可嵌入

随着时间流逝,产品需求可能对你类的行为有更多的要求。而该行为却与你类的核心功能没有半毛钱关系。也有可能是类的唯一一种实现,好比在一个选项卡的面板获取另一个选项卡的外部数据时,将这个选项卡面板中的内容变灰。你可能想把这些功能放在类的里面,但是它们不属于那里。选项卡条的责任在于管理选项卡。动画和获取数据是完全不同的两码事,也必须与选项卡条的代码分开。唯一一个让你的选项卡条不过时而又将那些额外的功能排除在外的方法是,允许将行为嵌入到代码当中。换句话说,通过创建事件,让它们在你的代码中与关键时刻挂钩,例如onTabChange, afterTabChange, onShowPanel, afterShowPanel等等。那样的话,他们可以轻易地与你的onShowPanel事件挂钩,写一个将面板内容变灰的处理器,这样就皆大欢喜了。JavaScript库让你可以足够容易地做到这一点,但是你自己写也不那么难。下面是使用YUI 3的一个例子。

<script type="text/javascript" src="http://yui.yahooapis.com/combo?3.2.0/build/yui/yui-min.js"></script>
<script type="text/javascript">
YUI().use(&#39;event&#39;, function (Y) {
function TabStrip() {
this.showPanel = function () {
this.fire(&#39;onShowPanel&#39;);
// 展现面板的代码
this.fire(&#39;afterShowPanel&#39;);
};
};
// 让TabStrip有能力激发常用事件
Y.augment(TabStrip, Y.EventTarget);
var ts = new TabStrip();
// 给TabStrip的这个实例创建常用时间处理器
ts.on(&#39;onShowPanel&#39;, function () {
//在展示面板之前要做的事
});
ts.on(&#39;onShowPanel&#39;, function () {
//在展示面板之前要做的其他事
});
ts.on(&#39;afterShowPanel&#39;, function () {
//在展示面板之后要做的事
});
ts.showPanel();
});
</script>
登入後複製

这个例子有一个简单的 TabStrip 类,其中有个showPanel方法。这个方法激发两个事件,onShowPanel和afterShowPanel。这个能力是通过用Y.EventTarget扩大类来实现的。一旦做成,我们就实例化了一个TabStrip对象,并将一堆处理器都分配给它。这是用来处理实例的唯一行为而又能避免混乱当前类的常用代码。


总结


如果你打算重用代码,无论是在同一网页,同一网站还是跨项目操作,考虑一下在类里面将其打包和组织起来。面向对象JavaScript很自然地帮助实现更好的代码组织以及代码重用。除此以外,有点远见的你可以确保代码具有足够的灵活性,可以在你写完代码后持续使用很长时间。编写可重用的不过时JavaScript代码可以节省你,你的团队还有你公司的时间和金钱。这绝对能让你大受欢迎。


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1660
14
CakePHP 教程
1416
52
Laravel 教程
1310
25
PHP教程
1260
29
C# 教程
1233
24
簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

PHP高階特性:物件導向程式設計的最佳實踐 PHP高階特性:物件導向程式設計的最佳實踐 Jun 05, 2024 pm 09:39 PM

PHP中OOP最佳實務包括命名約定、介面與抽象類別、繼承與多型、依賴注入。實戰案例包括:使用倉庫模式管理數據,使用策略模式實現排序。

探索Go語言中的物件導向編程 探索Go語言中的物件導向編程 Apr 04, 2024 am 10:39 AM

Go語言支援物件導向編程,透過型別定義和方法關聯實作。它不支援傳統繼承,而是透過組合實現。介面提供了類型間的一致性,允許定義抽象方法。實戰案例展示如何使用OOP管理客戶訊息,包括建立、取得、更新和刪除客戶操作。

Golang中有類似類別的物件導向特性嗎? Golang中有類似類別的物件導向特性嗎? Mar 19, 2024 pm 02:51 PM

在Golang(Go語言)中並沒有傳統意義上的類別的概念,但它提供了一種稱為結構體的資料類型,透過結構體可以實現類似類別的物件導向特性。在本文中,我們將介紹如何使用結構體實現物件導向的特性,並提供具體的程式碼範例。結構體的定義和使用首先,讓我們來看看結構體的定義和使用方式。在Golang中,結構體可以透過type關鍵字定義,然後在需要的地方使用。結構體中可以包含屬

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

Go語言的物件導向特性解析 Go語言的物件導向特性解析 Apr 04, 2024 am 11:18 AM

Go語言支援物件導向編程,透過struct定義對象,使用指標接收器定義方法,並透過介面實現多態。物件導向特性在Go語言中提供了程式碼重用、可維護性和封裝,但也存在缺乏傳統類別和繼承的概念以及方法簽章強制型別轉換的限制。

PHP物件導向程式設計的深入理解:物件導向程式設計的除錯技巧 PHP物件導向程式設計的深入理解:物件導向程式設計的除錯技巧 Jun 05, 2024 pm 08:50 PM

透過掌握追蹤物件狀態、設定斷點、追蹤異常和利用xdebug擴展,可以有效調試PHP物件導向程式碼。 1.追蹤物件狀態:使用var_dump()和print_r()檢視物件屬性和方法值。 2.設定斷點:在開發環境中設定斷點,偵錯器會在執行到達斷點時暫停,以便檢查物件狀態。 3.追蹤異常:使用try-catch區塊和getTraceAsString()取得異常發生時的堆疊追蹤和訊息。 4.利用偵錯器:xdebug_var_dump()函數可在程式碼執行過程中檢查變數的內容。

JavaScript和WebSocket:打造高效率的即時搜尋引擎 JavaScript和WebSocket:打造高效率的即時搜尋引擎 Dec 17, 2023 pm 10:13 PM

JavaScript和WebSocket:打造高效率的即時搜尋引擎引言:隨著網路的發展,使用者對即時搜尋引擎的要求也越來越高。傳統的搜尋引擎在進行搜尋時,使用者需要點擊搜尋按鈕後才能得到結果,這種方式無法滿足使用者對於即時搜尋結果的需求。因此,採用JavaScript和WebSocket技術來實現即時搜尋引擎成為了一個熱門的話題。本文將詳細介紹使用JavaScri

See all articles