摘要:如果要理解基于原型實現(xiàn)面向?qū)ο蟮乃枷耄敲蠢斫庵械萌齻€重要概念構(gòu)造函數(shù)原型原型鏈對幫助理解基于原型的面向?qū)ο笏枷刖惋@得尤為重要。函數(shù)對象的原型在中,函數(shù)是一種特殊的對象,所有的函數(shù)都是構(gòu)造函數(shù)的實例。
介紹
和java這種基于類(class-base)的面向?qū)ο蟮木幊陶Z言不同,javascript沒有類這樣的概念,但是javascript也是面向?qū)ο蟮恼Z言,這種面向?qū)ο蟮姆绞匠蔀?基于原型(prototype-base)的面向?qū)ο蟆km然說ES6已經(jīng)引入了類的概念來作為模板,通過關(guān)鍵字 “class” 可以定義類,但ES6的這種寫法可以理解為一種語法糖,它的絕大部分功能,ES5都可以做到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法而已。如果要理解基于原型實現(xiàn)面向?qū)ο蟮乃枷?,那么理解javascript中得三個重要概念: 構(gòu)造函數(shù)(constructor)、原型(prototype)、原型鏈(prototype chain) 對幫助理解基于原型的面向?qū)ο笏枷刖惋@得尤為重要。下面就重點介紹一下這幾個概念。
javascript對象結(jié)構(gòu)圖先來看一張來自mollypages.org 的javascript對象的結(jié)構(gòu)圖,下面的例子都按照這張圖闡述。
構(gòu)造函數(shù)(constructor)和原型 (prototype)構(gòu)造函數(shù)是用來初始化對象的,每個構(gòu)造函數(shù)都有一個不可枚舉的屬性,這就是原型(prototype).并且,每個prototype 都包含一個包含了不可枚舉屬性的constructor屬性,這個屬性始終會指向構(gòu)造函數(shù)。
javascript function Foo(){}; console.log(Foo.prototype.constructor === Foo); // true原型鏈(prototype chain) 使用new實例化的原型
每個被new實例化的對象都會包含一個__proto__ 屬性,它是對構(gòu)造函數(shù) prototype 的引用。
javascript function Foo(){}; var foo = new Foo(); console.log(foo.__proto__ === Foo.prototype); // ture
javascript function Foo(){}; console.log(Foo.prototype.__proto__ === Object.prototype); // true
上面返回true 的原因是Foo.prototype 是Object預(yù)創(chuàng)建的一個對象,是Object創(chuàng)建的一個實例,所以,F(xiàn)oo.prototype.__proto_ 是Object.prototype的引用。
我們可以來看一下原型鏈的脈絡(luò)。
函數(shù)(function)對象的原型在javascript中,函數(shù)是一種特殊的對象,所有的函數(shù)都是構(gòu)造函數(shù) Function 的實例。
javascript function Foo() {}; console.log(Foo.__proto__ === Object.prototype); //false console.log(Fool.__proto__ === Function.prototype); // true
從上面可以看出,函數(shù)Foo.__proto_ 指向到 Function.prototype, 說明函數(shù) Foo 是 Function的一個實例。
javascript function Foo(){}; console.log(Foo.__proto__ === Function.prototype); //true console.log(Foo.prototype.__proto__ === Object.prototype);//true
Foo.prototype 是Object預(yù)定義的對象,構(gòu)造函數(shù)為Object,所以__proto__指向 Object.prototype
從上面的圖我們可以看出, Object、Function、Array 等這些函數(shù),他們的構(gòu)造函數(shù)都是 Function 的實例。
基于原型鏈的繼承有了上面的基礎(chǔ)知識以后,我們就可以自己去基于原型鏈去封裝對象,實現(xiàn)javascript的繼承。先來看下面一個例子。
運行上面的例子,輸入 cat init 和 animal eat,說明cat 繼承了 Animal.prototype.eat 的方法。
我們來分析一下代碼。
1、Animal 的prototype中定義了 eat方法。
2、將Empty.prototype 指向 Animal.prototype , 所以 Empty.prototype 中也存在eat方法.
3、Cat.prototype == new Empty(),所以 Cat.prototype.__proto_ === Animal.__proto_.
4、重新為Cat指定constructor為Cat,否則Cat不存在constructor。
這樣就完成了繼承,原型鏈?zhǔn)沁@樣的:
這樣我們用原型鏈的方式實現(xiàn)了一個簡單的繼承方式。
參考基于原型的javascript 面向?qū)ο缶幊?/p>
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/85725.html
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:面向?qū)ο竺嫦驅(qū)ο蟮母攀雒嫦驅(qū)ο笫鞘裁疵嫦驅(qū)ο缶幊痰娜Q是,簡稱。面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實世界模型的一種編程。面向?qū)ο缶幊炭梢钥醋鍪鞘褂靡幌盗袑ο笙嗷f(xié)作的軟件設(shè)計。面向?qū)ο缶幊痰纳礁柚饕奶卣魇欠庋b繼承多態(tài)。 面向?qū)ο?面向?qū)ο蟮母攀?面向?qū)ο笫鞘裁?面向?qū)ο缶幊痰娜Q是Object Oriented Programming,簡稱OOP。面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實...
摘要:說到底面向?qū)ο蟛攀浅绦蛘Z言的根本。其實面向?qū)ο缶幊陶f的就是自定義對象。里并沒有類的概念,所以嚴(yán)格上來講這是個假的面向?qū)ο罄锏拿嫦驅(qū)ο缶幊态F(xiàn)在好了,終于聽到別人鄙視我們了,給我們提供了類這個概念,其實是向傳統(tǒng)語言更靠齊了。 通過前兩篇文章,我們了解了對象的概念以及面向?qū)ο罄锏南嚓P(guān)概念等知識,那前面說了對象分類里的前兩種,這篇文章要詳細(xì)去說第三種自定義對象,那真正的好戲這就來了! 面向?qū)ο?..
閱讀 1264·2021-11-10 11:35
閱讀 3014·2021-09-24 10:35
閱讀 3090·2021-09-22 15:38
閱讀 2888·2019-08-30 15:43
閱讀 1431·2019-08-29 18:39
閱讀 2683·2019-08-29 15:22
閱讀 2867·2019-08-28 18:17
閱讀 677·2019-08-26 13:37