1. 程式人生 > >prototype.js 讓你更深入的瞭解javascript的面向物件特性

prototype.js 讓你更深入的瞭解javascript的面向物件特性

js是一門很強大的語言,靈活,方便。 目前我接觸到的語言當中,從語法角度上講,只有 Ruby 比它更爽。

不過我接觸的動態語言只有: js ruby python flash的as 簡單的幾門, 應該算是井底之蛙之見。

js 語法成分簡單,沒有 ruby 語言複雜。所以有時候我覺得她更乾淨(Ruby Fans 不要攻擊我哦,我也是很愛很愛很愛Ruby的)!

Prototype.js 無疑是 js的漂亮之作,從它身上應該可以學到一些東西。

如果你用 js 在頁面僅僅能寫出 if, alert等簡單的驗證程式碼,或者想多瞭解一下Js, 那麼此文可能對你有幫助。

好了,開始吧。

現在我突然想起了 Thinking in java 中的 "一切皆是對像", 其實我覺得這句話 有點不適合 java 反倒是更適合 js


1.怎樣構造(初始化)物件?

js 程式碼
  1. var Prototype = {   
  2.   Version: '1.5.0_rc1',   
  3.   ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)',   
  4.   emptyFunction: function() {},   
  5.   K: function(x) {return x}   
  6. }   

就這樣,初始化了一個物件(名字就叫 Prototype),以及物件的四個成員: Version, ScriptFragment, emptyFunction, K

我們也來試試:

js 程式碼
  1. var bbs = {   
  2.  name: 'JavaEye',   
  3.  version: '2.0',   
  4.  describe: "做最棒的軟體開發交流區",   
  5.  sayHello: function() { alert("hello, i'm javaeye! ") }   
  6. }  

於是你可以這樣使用: bbs.name 或 bbs.sayHello()

看到嗎? sayHello 是一個方法哦,不要驚慌,"一切都是物件",所以它和 name 是一樣的,只不過初始化,或定義的語法不一樣。想起 js 中的正則表示式中的那兩個杆杆了嗎? 可愛吧!

方法是物件,所以它可以被當作引數傳遞,或者作為方法的返回值。

所以 Prototype 中有一個 Version 屬性,還有一個匹配 script 的正則式字串, 一個空方法emptyFunction,還有一個方法 K, 它僅僅返回引數。

沒問題吧,繼續!

2. 建構函式?

先讓我們寫段程式碼吧(中學時,我語文極差(大學沒語文了),我想寫程式碼讓你們明白我心裡真實的想法):

js 程式碼
  1. var Person = function(name) { // 這裡 Person 是一個方法 
  2. this.name = name;   
  3. }   
  4. var bencode = new Persion("bencode");  // 這裡像Java吧! 
  5. alert(bencode.name);  

先看結果:
從 alert(bencode.name); 可以知道,bencode是物件, 而 name 就是 bencode 的屬性, 它被正確地初始化為 "bencode"

所以 var bencode = new Persion("bencode"); 就是構造了一個新的物件,Person() 相當於建構函式

所以 new 這個關鍵字, 就是構造一個新的物件,並且在這個物件上呼叫相應的方法,並將這個物件返回。

按上面說: 方法 如果用在 在 new 後面,就相當於成了構造函數了。

話又說回來了, 如果 var bencode = new Persion("bencode") 是 構造了一個物件,像Java, 那麼 Person 是不是類呢?
可是 Person 不是方法嗎? 可是方法不也是物件嗎? 類也是物件?

一切皆物件?

本來無一物!

js 程式碼
  1. var Class = {   
  2.   create: function() {   
  3. returnfunction() {   
  4. this.initialize.apply(this, arguments);   
  5.     }   
  6.   }   
  7. }  

初始化一個 Class 物件, 它有一個成員,是一個方法, 這個方法返因另一個方法(方法是物件,所以可以作為引數或者返回值)

所以如果我們這麼做: 

js 程式碼
  1. var A = Class.create(); // 此時 A 是一個方法,方法體,下面解釋 
  2. var a = new A(...);  // 對方法使用 new 操作符,就是構造一個新的物件,然後在這個物件上呼叫這個方法( 現在是 A)

上面分析說? A相當於類, 哈哈 Class.create();  // 終於名副其實
var a = new A(...);  // 也是相當地直觀, 就是構造一個新的物件,型別 是A

new 操作符構造了物件,並呼叫了 方法, 這個方法到底做了什麼呢? 也就是上面沒有分析的東東,看看先:

js 程式碼
  1. var Class = {   
  2.   create: function() {   
  3. returnfunction() {  // 見[1] 
  4. this.initialize.apply(this, arguments);  // 見[2] 
  5.     }   
  6.   }    
  7. }  

[1]. new 操作符,就會在新產生的物件上呼叫這個方法
[2]. 哦? 這裡就是呼叫 this 物件上的 initialize方法, 並傳遞 arguments
  換句話說,就是把構造的任務委託給 initialize 方法
  initialize? 哪裡來? 見下面,類的擴充套件(繼承)
  
3. Prototype?

看段老程式碼:

js 程式碼
  1. var Person = function(name) {   
  2. this.name = name;   
  3. }   
  4. var bencode = new Person("bencode");  

bencode不是一個自閉的人,他應該可以向javaeye介紹一下自己。
像這樣:

js 程式碼
  1. bencode.sayHello();   


 
假如不能實現以上功能的話, 上面的 new,上面所有的東東都等於垃圾。

所以。需要給 Person 類加"例項方法"

題外話: 靜態方法如何新增? 看上面的 Class.create, 僅僅是一個物件的成員而已

好, 再來一段 (為了完整性,上面的幾句話,再抄一次)

js 程式碼
  1. var Person = function(name) {   
  2. this.name = name;   
  3. }   
  4. Person.prototype = {  // protype 是啥? 
  5.  sayHello: function() {   
  6.   alert("hi, javaeye, I'm " + this.name);   
  7.  }   
  8. }   
  9. var bencode = new Person("bencode");   
  10. bencode.sayHello();  

執行程式碼,通過!

prototype是啥? 請暫時忘記 Prototype(prototype.js) 這個庫,名字一樣而已!

讓我們再從結果上去分析(第一次我們用這種方法分析而得出了 new 的作用),

我們在思考:
 要想 bencode.sayHello() 正常執行
 bencode 是一個物件, 這是我們已經知道的
 sayHello() 應該是 bencode 這個物件的方法才可以
 
 可是bencode 這個物件是 new 操作符產生的, 而 new 此時作用於 Person 這個 "類"
 那麼, 哦? 那麼有兩種可能:
 1. new 產生的那個新物件是不是就是 Person.prototype
 2. Person.prototype 中的成員 將會被 new 操作符新增到 新產生的物件中

再看:

js 程式碼
  1. Person.prototype = {   
  2.  sayHello: function() {   
  3.   alert("hi, javaeye, I'm " + this.name); // 這裡有this 
  4.  }   
  5. }  

this.name, 這裡的 this 指什麼?所以第一個可能講不通呀

回憶起這段:

js 程式碼
  1. var Person = function(name) {   
  2. this.name = name;   
  3. }  

如果這裡的 this 代表著新產生的物件的話。
那麼第二種情況就講得通了, new 將會把 Person.prototype 這個物件的成員放到 這個新物件中。 與當前行為相符。

所以: Person 的 Prototype 物件中的 成員, 將會被新增到 新產生的物件 中(我是這樣理解的)
(不知道 Js直譯器是不是開源的, 有空我得去看看,怎麼實現的。)

嘿,預設的 Prototype 就是 Object 哦!

4. 擴充套件?繼承?

什麼是擴充套件?啥是繼承? ! 我從爸爸那得到了什麼?
想不通!

還是實際點:

有一個類A, 它有一個 sayHello方法

js 程式碼
  1. var A = function() {   
  2. }   
  3. A.prototype = {   
  4.  sayHello: function() {   
  5.   alert("sayHello A")   
  6.  }   
  7. }   

我想構造一個 B 類,讓他繼承 A 物件, 這句話太抽象。

其實我們可能想這樣:

js 程式碼
  1. var b = new B();   
  2. b.sayHello();  // 呼叫 A 的 sayHello

這應該是繼承的第一層含義(重用)

怎麼辦到呢?

var B = function() { // 這裡是有一個B類了
}

怎麼樣新增"例項方法"?  快點想起 Prototype!!!

B.prototype = A.prototype

這樣行了嗎? 恭喜, 執行通過!

讓我們整合一次

js 程式碼
  1. var A = function() {   
  2. }   
  3. A.prototype = {   
  4.  sayHello: function() {   
  5.   alert("sayHello A");   
  6.  }   
  7. }   
  8. var B = function() {   
  9. }   
  10. B.prototype = A.prototype;   
  11. var b = new B();   
  12. b.sayHello();    

可是如果 B 是這樣呢?

js 程式碼
  1. var B = function() {   
  2. }   
  3. B.prototype = {   
  4.  sayHi: function() {   
  5.   alert("sayHi B");   
  6.  }   
  7. }  

我們是不是應該將 A.prototype 中的內容新增到 B.prototype 物件中,而不是代替它呢? 當然。

這樣才能"擴充套件"

題外話?多型在哪裡? 嘿嘿

好了,足夠多了, 那prototype.js 是怎麼樣"擴充套件"的呢?

js 程式碼
  1. Object.extend = function(destination, source) {   
  2. for (var property in source) {   
  3.     destination[property] = source[property];   
  4.   }   
  5. return destination;   
  6. }  

這個只是簡單地把 source 的成員, 新增到 destination 物件中嘛, 哪裡看得出擴充套件?

如果我這樣呢?

js 程式碼
  1. var A = function() {   
  2. }   
  3. A.prototype = {   
  4.  sayHello: function() {   
  5.   alert("sayHello A")   
  6.  }   
  7. }   
  8. var B = function() {   
  9. }   
  10. Object.extend(B.prototype, A.prototype); // 先新增父類(A)成員 
  11. Object.extend(B.prototype, { // 再新增B類成員, 如果是同名,則覆蓋,行為符合 "多型" 
  12.  sayHi: function() {   
  13.   alert("sayHi B");   
  14.  }   
  15. });   

回憶剛才的 Class.create():

js 程式碼
  1. var Person = Class.create();   
  2. var bencode = new Person("bencode");  

剛才說過, 呼叫 new 時, 將會建立一個新物件,並且呼叫 Person 方法, Person 方法會委託給 "新產生物件"的 initialize方法

怎麼樣給新產生物件新增 initialize 方法? 哈哈,輕鬆

js 程式碼
  1. Object.extend(Person.prototype, {   
  2.  initialize: function() {   
  3. this.name = name;   
  4.  } //, 
  5. // 下面可以新增其他例項方法。 
  6. });  


所以, 我們使用 Prototype 建立類一般格式是這樣的:

js 程式碼
  1. 相關推薦

    prototype.js 深入瞭解javascript面向物件特性

    js是一門很強大的語言,靈活,方便。 目前我接觸到的語言當中,從語法角度上講,只有 Ruby 比它更爽。 不過我接觸的動態語言只有: js ruby python flash的as 簡單的幾門, 應該算是井底之蛙之見。 js 語法成分簡單,沒有 ruby 語言複雜。所

    javascript深入瞭解面向物件

    目標:以執行效率最高的方式實現javascript的面向物件模式。 實現目標方式:從最基礎的實現開始一步一步優化到最後的實現方式。請執行或者讀懂每一段程式碼。 一,建立物件: var people1 = new Object();//只有物件上才能新增屬性 p

    全方位深入理解JavaScript面向物件

    JavaScript面向物件程式設計 本文會碰到的知識點: 原型、原型鏈、函式物件、普通物件、繼承 讀完本文,可以學到 面向物件的基本概念 JavaScript物件屬性 理解JavaScript中的函式物件與普通物件 理解prototype和proto

    5個技巧好的編寫 JavaScript(ES6) 中條件語句

    使用 JavaScript 時,我們經常需要處理很多條件語句,這裡分享5個小技巧,可以讓你編寫更好/更清晰的條件語句。 1.使用 Array.includes 來處理多個條件 我們來看看下面的例子: JavaScript 程式碼: // condition functi

    智能家居入口科普 好了解智能家居

    布局 廠商 習慣 轉變 開始 智能路由 管家 創建 解決 自從智能家居這個行業誕生以來,這個入口的問題就一直沒有間斷,入口就是管理智能家居的總和系統,作為智能家居,如果是對每個產品分別執行指令,那肯定就失去了智能家居的意義,這時,一個很好地中控主機就顯得尤為重要。當智能家居

    圖說js中的this——深入理解javascript中this指針

    前端 javascript this沒搞錯吧!js寫了那麽多年,this還是會搞錯!沒搞錯,javascript就是回搞錯!…………在寫java的時候,this用錯了,idea都會直接報錯!比如……但是,js,……idea,愛莫能助了……在面向對象編程裏有兩個重要的概念:一個是類,一個是實例化的對象,類是一個

    值錢的方法:培養稀缺(追逐新技術,淬煉已有技能、做到出類拔萃,尋找自己所在的行業痛點,App開發者是市場動態平衡的典型)

    問題 全面 bin o2o 策略 軟件公司 前瞻 籃球場 rdquo 一個開發者,如何才能更值錢? 答案非常簡單:掌握稀缺資源。 那麽,怎樣才能持續不斷地掌握稀缺資源,讓自己更值錢呢? 請看接下來介紹的 2 種識別稀缺的方法和 2 種培養稀缺的策略。 稀缺資

    超級眼好的管理員工

    個人 工資 實時監控 等等 裝包 網上 必備 泄露 等你 對於現代企業而言,網絡無疑是一把雙刃劍。何以解憂? 隨著企業信息建設的普及,它是獲得客戶、供應商以及合作夥伴的必備手段和信息的必要來源。但是分散員工精力,降低生產力的根源。 重要資料的泄漏以及不可控的安全隱患使企業面

    用Unity做遊戲,需要深入瞭解一下IL2CPP

    這次我們翻譯了一篇Unity官方部落格上的文章,原文題目為AN INTRODUCTION TO IL2CPP INTERNALS ,作者是從事Unity軟體開發的Joshua Peterson。文章的看點在於,它是以IL2CPP內部開發人員的角度來講述的,所以對於開發者來說非常有參考價值。 如果

    深入瞭解JavaScript底層原理

    [TOC] 1. 七種內建型別 基本型別: null,undefined,boolean,number(浮點型別),string,symbol(es6)。 物件:Object。 複製程式碼 型別轉換 typeof: typeof 1 // 'number' typeof '1' // 's

    理解五個基本概念,像機器學習專家

    大多數人可能對機器學習有點恐懼或困惑。 腦子中會有它到底是什麼,它有什麼發展方向,我現在可以通過它掙錢嗎等等這樣的問題。 這些問題的提出都是有依據的。事實上,你可能沒有意識到自己其實多年來一直在訓練機器學習模型。你看過蘋果手機或者是Facebook上的照片吧? 你知道它如何向你展示一組面孔並要求你識別它

    有關!高鐵站採用的室內定位技術有安全感

    如今,高鐵出行已經成為人們中短距出行的首選,高鐵站隨之成為最密集的人流集聚地之一, 因此如何對之進行有效的管理,已成為高鐵站人員管理工作的重要內容。 視訊監控系統 視訊監控系統是保障高鐵安全運營的一項重要措施,但要同時滿足公安、安監、客運、排程、車務、機務、供電等業務部門及防災監控、救援搶

    學習C語言前知道這些事情,快入門

    C語言基本常識 計算機語言:把人與計算機之間交流的語言叫做計算機語言 計算機語言分為高階語言和低階語言 高階語言:遠離硬體 低階語言:貼近硬體 指令:是指計算機執行某種操作的命令。它由一串二進位制數碼組成。 一條指令通常由兩個部分組成:操作碼 地址碼。 操作碼:指

    如果未曾深入瞭解python,請先看看這篇python簡史!

      python與人工智慧緊緊的聯絡在一起,現在很多年輕的開發者都開始學習Python,文章清晰且幽默的講述了python的發展史,希望對還在自學python的你有些幫助,或重拾自學python的激情。 學習Python中有不明白推薦加入交流群   &n

    26個英文字母的另一種讀法,容易聽懂

    近期看了不少關於戰爭的電影和電視劇,不過都是英文為主的,就當學英語了。裡面經常會說一些軍用的詞彙,簡潔明瞭,感覺碉堡了,就像國內的黑話和切口一樣。例如那款FPS單機遊戲《三角洲部隊》,英文名是《Delta force》,其實Delta是D的另一種讀法。所以查了查這些次的意思,原來是一些縮寫或者特定用詞防止混淆

    js的rem彈性佈局適配所有解析度(含豎屏適配)

    <!doctype html> <html> <head>     <meta charset="utf-8" />     <title>自動計算字型</title>     <meta nam

    阿里程式設計師帶全面深入瞭解正則表示式

    在日常工作中,經常會用到正則操作。但是對於大多數人來說,操作正則表示式簡直就是抓瞎。 本篇文章主要整理了正則表示式匹配的規則,使用中的一些要點,以及用圖形化的方式列舉出一些常見的正則表示式,希望能給大家帶來一定的幫助,能在以後的工作中,用上正則,愛上正則。 PS:不同語言中的正則表示式的規則

    Java -- 最詳細基礎部分面試題及答案(需深入瞭解

    Java基礎方面: 1、作用域public,private,protected,以及不寫時的區別答:區別如下:作用域           當前類同一package     子孫類其他packagepublic              √                √  

    介面回撥,用最簡單的一個匿名內部類來講解(附介面回撥高階應用場景,對介面的瞭解登堂入室)

    介面回撥,是Java開發者必須要學的一個東西,可是他呢,書上沒有,大神部落格裡也沒有,所以導致了有部分小夥紙並不瞭解這個知識,所以這裡做一個最簡單的講解。 (先不牽扯什麼非同步回撥、同步回撥) 首先,只需要記住一點,介面回撥的含義就是把程式碼換個地方寫。 正常我們是這

    Ansible部署Node.js,從簡操作

    下面我們將要在我們的CentOS6.x伺服器上配置Nodejs,啟動一個簡單的nodejs例項,這個伺服器有很簡單的架構。 開始了,首先建立一個playbook檔案,我們儘量讓它保持簡單。 --- - hosts: all  tasks: 定義一些執行這個playbook的主機,然後下面列出一