摘要:以下內(nèi)容均基于本人對高級程序設(shè)計(jì)第三版小節(jié)的理解先看一下父類私有受保護(hù)成員,只允許在父類的構(gòu)造函數(shù)中賦值公有成員引用類型的成員構(gòu)造函數(shù)中的方法,打印一些基本信息原型中的方法,將構(gòu)造函數(shù)中的非函數(shù)成員以格式打印方式一原型鏈繼承實(shí)現(xiàn)方式子類的原
先看一下父類以下內(nèi)容均基于本人對《JavaScript高級程序設(shè)計(jì)》第三版6.3小節(jié)的理解
function Animal(name) { var name = name; //"私有(受保護(hù))"成員,只允許在父類的構(gòu)造函數(shù)中賦值 this.food = undefined; //"公有"成員 //引用類型的成員 this.birthday = { year: undefined }; //構(gòu)造函數(shù)中的方法,打印一些基本信息 this.greeting = function() { console.log("Hi, my name is {" + name + "} I like eat {" + this.food + "} and my birth year is {" + this.birthday.year + "}"); }; //原型中的方法,將構(gòu)造函數(shù)中的非函數(shù)成員以JSON格式打印 Animal.prototype.briefInfo = function() { var brief = { name: name, food: this.food, birthday: this.birthday }; console.log(JSON.stringify(brief)); }; }方式一:原型鏈繼承
實(shí)現(xiàn)方式:子類的原型指向父類的實(shí)例
子類:
function Dog() {} Dog.prototype = new Animal(); //原型指向父類的實(shí)例
測試:
var dog1 = new Dog(); dog1.food = "shit"; dog1.birthday.year = 2015; var dog2 = new Dog(); dog2.food = "bones"; dog2.birthday.year = 2016; dog1.greeting(); //console: Hi, my name is {undefined} I like eat {shit} and my birth year is {2016} dog2.greeting(); //console: Hi, my name is {undefined} I like eat {bones} and my birth year is {2016} dog1.briefInfo(); //console: {"food":"shit","birthday":{"year":2016}} dog2.briefInfo(); //console: {"food":"bones","birthday":{"year":2016}} //以上, //birthday是引用類型的屬性,所以dog1的birthday.year被dog2覆蓋了; //無法給dog1和dog2的name賦值
存在的問題:
引用類型的對象會被子類的所有實(shí)例共享(1.1)
無法在創(chuàng)建子類的實(shí)例時,給父類的構(gòu)造函數(shù)傳遞參數(shù)(1.2)
方式二:借用構(gòu)造函數(shù)(偽造對象、經(jīng)典繼承)實(shí)現(xiàn)方式:在子類的構(gòu)造函數(shù)中利用call(或者apply)方法執(zhí)行父類構(gòu)造函數(shù)(問題1.2解決),將執(zhí)行對象設(shè)為子類的this,相當(dāng)于把父類構(gòu)造函數(shù)中的成員拷貝了一份到子類(問題1.1解決)
子類
function Dog(name) { Animal.call(this, name); }
測試
var dog1 = new Dog("tom"); dog1.food = "shit"; dog1.birthday.year = 2015; var dog2 = new Dog("mike"); dog2.food = "bones"; dog2.birthday.year = 2016; dog1.greeting(); //console: Hi, my name is {tom} I like eat {shit} and my birth year is {2015} dog2.greeting(); //console: Hi, my name is {mike} I like eat {bones} and my birth year is {2016} //briefInfo是父類原型中的屬性,并沒有被繼承,以下語句會報錯 dog1.briefInfo(); //error: dog1.briefInfo is not a function dog2.briefInfo(); //error: dog2.briefInfo is not a function
存在的問題:
父類原型中定義的屬性無法被繼承
綜合方式一方式二,一種很明顯的方式呼之欲出了:
方式三:組合繼承實(shí)現(xiàn)方式:結(jié)合原型鏈繼承和經(jīng)典繼承
子類
function Dog(name) { Animal.call(this, name); //經(jīng)典繼承 } Dog.prototype = new Animal(); //原型鏈繼承
測試
var dog1 = new Dog("tom"); dog1.food = "shit"; dog1.birthday.year = 2015; var dog2 = new Dog("mike"); dog2.food = "bones"; dog2.birthday.year = 2016; dog1.greeting(); //console: Hi, my name is {tom} I like eat {shit} and my birth year is {2015} dog2.greeting(); //console: Hi, my name is {mike} I like eat {bones} and my birth year is {2016} dog1.briefInfo(); //console: {"name":"tom","food":"shit","birthday":{"year":2015}} dog2.briefInfo(); //console: {"name":"mike","food":"bones","birthday":{"year":2016}} //終于得到了預(yù)期的結(jié)果,算是較好的實(shí)現(xiàn)了繼承。 //但是,并不完美
存在的問題
父類的構(gòu)造函數(shù)被調(diào)用了兩次
為了引出下一個繼承方式,先將函數(shù)的繼承放在一邊,看一下js中對象的繼承
(摘抄原文)
1. 原型式繼承
var person = { name: "martin" firend: ["bob", "steven"] }; function object(o) { function F() {}; F.prototype = o; return new F(); } var anotherPerson = object(person); //antherPerson繼承了person2. 寄生式繼承
function createAnother(original) { var clone = object(original); //原型式繼承定義的方法 //擴(kuò)展對象 clone.sayHi = function() { console.log("hi"); } return clone; }
回到正題,接下來介紹一顆 “銀彈”
方式四:寄生組合式繼承實(shí)現(xiàn)方式:
利用經(jīng)典繼承拷貝父類構(gòu)造中的屬性到子類
利用原型式繼承創(chuàng)建一個繼承父類原型的對象
將該對象的constructor屬性指向子類的構(gòu)造函數(shù)(寄生式繼承:擴(kuò)展對象)
將子類的prototype指向該對象
子類
function Dog(name) { Animal.call(this, name); } function F() {} var supProto = Animal.prototype; F.prototype = supProto; var subProto = new F(); subProto.constructor = Dog; Dog.prototype = subProto;
測試
var dog1 = new Dog("tom"); dog1.food = "shit"; dog1.birthday.year = 2015; var dog2 = new Dog("mike"); dog2.food = "bones"; dog2.birthday.year = 2016; dog1.greeting(); //console: Hi, my name is {tom} I like eat {shit} and my birth year is {2015} dog2.greeting(); //console: Hi, my name is {mike} I like eat {bones} and my birth year is {2016} dog1.briefInfo(); //console: {"name":"tom","food":"shit","birthday":{"year":2015}} dog2.briefInfo(); //console: {"name":"mike","food":"bones","birthday":{"year":2016}}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79731.html
摘要:中的繼承并不是明確規(guī)定的,而是通過模仿實(shí)現(xiàn)的。繼承中的繼承又稱模擬類繼承。將函數(shù)抽離到全局對象中,函數(shù)內(nèi)部直接通過作用域鏈查找函數(shù)。這種范式編程是基于作用域鏈,與前面講的繼承是基于原型鏈的本質(zhì)區(qū)別是屬性查找方式的不同。 這一節(jié)梳理對象的繼承。 我們主要使用繼承來實(shí)現(xiàn)代碼的抽象和代碼的復(fù)用,在應(yīng)用層實(shí)現(xiàn)功能的封裝。 javascript 的對象繼承方式真的是百花齊放,屬性繼承、原型繼承、...
摘要:和構(gòu)造函數(shù)前面提到,是個內(nèi)置隱藏屬性,雖然在可以通過訪問,但是其設(shè)計(jì)本意是不可被讀取和修改的,那么我們?nèi)绾卫迷玩渷斫⒗^承關(guān)系提供了關(guān)鍵字。到這兒,思路就清晰了,怎么讓對象和對象的相連實(shí)現(xiàn)繼承只需把的構(gòu)造函數(shù)的連接到就行了。 什么是繼承? 大多數(shù)人使用繼承不外乎是為了獲得這兩點(diǎn)好處,代碼的抽象和代碼的復(fù)用。代碼的抽象就不用說了,交通工具和汽車這類的例子數(shù)不勝數(shù),在傳統(tǒng)的OO語言中(...
摘要:首先,需要來理清一些基礎(chǔ)的計(jì)算機(jī)編程概念編程哲學(xué)與設(shè)計(jì)模式計(jì)算機(jī)編程理念源自于對現(xiàn)實(shí)抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機(jī)制一直以來都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因?yàn)榻^大多數(shù)人沒有想要深刻理解這個機(jī)制的內(nèi)涵,以及越來越多的開發(fā)者缺乏計(jì)算機(jī)編程相關(guān)的基礎(chǔ)知識。對于這樣的開發(fā)者來說 J...
摘要:前言作為中最重要的內(nèi)容之一,繼承問題一直是我們關(guān)注的重點(diǎn)。如果一個類別繼承自另一個類別,就把這個稱為的子類,而把稱為的父類別也可以稱是的超類。 前言 作為 JavaScript 中最重要的內(nèi)容之一,繼承問題一直是我們關(guān)注的重點(diǎn)。那么你是否清晰地知道它的原理以及各種實(shí)現(xiàn)方式呢 閱讀這篇文章,你將知道: 什么是繼承 實(shí)現(xiàn)繼承有哪幾種方式 它們各有什么特點(diǎn) 這里默認(rèn)你已經(jīng)清楚的知道構(gòu)造函...
摘要:繼承前言作為一門輕量級的腳本語言在和的橫空出世之后將其推向的新的高度雖然中出現(xiàn)的新的生成對象的類語法格式但依然為的語法糖而我們依然有必要從的原生實(shí)現(xiàn)入手來了解它的繼承實(shí)現(xiàn)方式給出了更加簡潔的固定的類聲明方式有興趣的可以查看阮一峰的入門下面給 javascript繼承 前言 javascript作為一門輕量級的腳本語言在ES6和node.js的橫空出世之后將其推向的新的高度,雖然 ES6...
閱讀 2222·2021-11-18 10:02
閱讀 3480·2021-11-15 11:36
閱讀 1116·2019-08-30 14:03
閱讀 725·2019-08-30 11:08
閱讀 2761·2019-08-29 13:20
閱讀 3287·2019-08-29 12:34
閱讀 1375·2019-08-28 18:30
閱讀 1642·2019-08-26 13:34