摘要:首先定義空函數(shù)這個不用解釋,然后把這個空函數(shù)的原型指向為的原型,然后再把的原型指向這個新的對象,一個完美傳遞最后,在把原型的構(gòu)造方法定義成華麗的轉(zhuǎn)身,結(jié)果如下結(jié)果還是不對,于是我又在大神的肩膀上墊了一下腳。
總是聽說面向?qū)ο螅?,繼承,__proto__,prototype,constructor.......于是乎小整理一下。
首先說,JS里的繼承是怎么弄的呢?
首先創(chuàng)建類(Person)
var Person = { male: 0, age:0, name:"nothing", say:function(){ console.log("Hello World"); } }
如何創(chuàng)建一個人呢?
var createPerson = function(){ return Object.create(Person); }
創(chuàng)建學(xué)生
var Student = createPerson(); Student.say() //Hello World Student.__proto__ === Person //true Student.constructor === Person //Student的構(gòu)造器還是Object
從這個可以看出什么呢?可以看出所謂的繼承,就是下面的代碼而已:
SSSSS.__proto__ = BBBBB
但是呢?也沒有prototype啥關(guān)系嘛,因為壓根就和他沒關(guān)系,好像也不太好,換一種寫法好了。
function Person (props){ this.name = props.name || "nothing"; this.male = props.male || 0; this.age = props.age || 0; this.say = function(){ console.log("Hello world!"); } }
繼續(xù)創(chuàng)建student
var Student = new Person(); Student.__proto__ === Person.prototype //true Student.constructor === Person //true Student.say() //Hello world!
從上面代碼可以看出,Student繼承了Person.
如果我們想改變一下呢?
Student.say = function(){ console.log("Hello teacher, my name is " + this.name);//Hello teacher, my name is nothing }
那好,再創(chuàng)建一個coder類
var Coder = new Person(); Coder.say(); //Hello world!
這個不錯嘛,這樣在想創(chuàng)建Coder的子類,js和html,那就修改一下代碼
function Coder (props){ Person.call(this,props); this.tip = props.tip?props.tip.toUpperCase():""; this.intro = function(){ console.log("I know "+(this.tip?this.tip:"nothing")); } this.say= function(){ console.log("hello, my name is " + this.name); } } var JSer = new Coder({ name:"Tony", age:26, tip:"js" }); var htmler = new Coder({ name:"Jermy", age:26, tip:"html" }); JSer.say(); //hello, my name is Tony htmler.say(); //hello, my name is Jermy JSer.intro(); //I know JS htmler.intro();//I know HTML
這樣得到了我們想要的結(jié)果,驗證一下繼承關(guān)系:
JSer instanceof Coder; //true htmler instanceof Coder;//true Coder instanceof Person;//false
這樣就不好了,為什么不是繼承關(guān)系呢?查看一下Coder情況如何?
Coder.__proto__ === Person.prototype; //false Coder.__proto__ //function () { [native code] }
看來問題就出在這里,寫一個中間函數(shù)補充一下?
var pass = function(child,parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }
為了實現(xiàn)這一點,參考道爺(就是發(fā)明JSON的那個道格拉斯)的代碼,中間對象可以用一個空函數(shù)F來實現(xiàn),大神寫的代碼,就是特么讓人深思。
仔仔細(xì)細(xì)想了下,我個人是這么理解的。
首先定義空函數(shù)這個不用解釋,然后把這個空函數(shù)的原型指向為Parent的原型,然后再把Child的原型指向這個新的F對象,一個完美傳遞;
最后,在把Child原型的構(gòu)造方法定義成Child;
華麗的轉(zhuǎn)身,結(jié)果如下:
function Coder (props){ Person.call(this,props); this.tip = props.tip?props.tip.toUpperCase():""; this.intro = function(){ console.log("I know "+(this.tip?this.tip:"nothing")); } this.say= function(){ console.log("hello, my name is " + this.name); } } var pass = function(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; } pass(Coder, Person); var JSer = new Coder({ name:"Tony", age:26, tip:"js" }); var htmler = new Coder({ name:"Jermy", age:26, tip:"html" }); JSer.say(); //hello, my name is Tony htmler.say(); //hello, my name is Jermy JSer.intro(); //I know JS htmler.intro();//I know HTML JSer instanceof Coder; //true htmler instanceof Coder;//true Coder instanceof Person;//false
結(jié)果還是不對,于是我又在大神的肩膀上墊了一下腳。
var pass = function(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.__proto__ = new F(); Child.__proto__.constructor = Child; }
結(jié)果就正確了......
又查了一下,總結(jié)一下:
所有的對象都有__proto__屬性,該屬性對應(yīng)該對象的原型.
所有的函數(shù)對象都有prototype屬性,該屬性的值會被賦值給該函數(shù)創(chuàng)建的對象的_proto_屬性.
所有的原型對象都有constructor屬性,該屬性對應(yīng)創(chuàng)建所有指向該原型的實例的構(gòu)造函數(shù).
函數(shù)對象和原型對象通過prototype和constructor屬性進行相互關(guān)聯(lián).
雖說弄懂了些表面的東西,實際上最主要的原因還是沒明白,那就是原型鏈到底有什么用呢?
好了,以上就是今天總結(jié)的一些內(nèi)容,希望相互學(xué)習(xí)幫助,能夠在未來更好的工作生活。
信息來源:
(↓相關(guān)一些對我?guī)椭艽?,Git的學(xué)習(xí)就是在這里看的,說的很詳細(xì)也很生動↓)
廖雪峰JavaScript教程
JS原型、原型鏈深入理解
深入分析js中的constructor 和prototype
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/83121.html
摘要:中的和是一門很靈活的語言,尤其是。即然是面向?qū)ο蟮木幊陶Z言,那也是不可或缺的。在中,永遠(yuǎn)指向的是他的調(diào)用者。定義是存在于實例化后對象的一個屬性,并且指向原對象的屬性。我們在擴展的時候,同時父類也會有對應(yīng)的方法,這很顯然是一個很嚴(yán)重的問題。 javascript中的this和new javascript是一門很靈活的語言,尤其是function。他即可以以面向過程的方式來用,比如: f...
摘要:面向?qū)ο笾杏腥筇卣?,封裝,繼承,多態(tài)。這不僅無法做到數(shù)據(jù)共享,也是極大的資源浪費,那么引入對象實例對象的屬性指向其構(gòu)造函數(shù),這樣看起來實例對象好像繼承了對象一樣。實例對象的原型指向其構(gòu)造函數(shù)的對象構(gòu)造器的指向。 前言 為什么說是再談呢,網(wǎng)上講解這個的博客的很多,我開始學(xué)習(xí)也是看過,敲過就沒了,自以為理解了就結(jié)束了,書到用時方恨少啊。實際開發(fā)中一用就打磕巴,于是在重新學(xué)習(xí)了之后分享出來...
摘要:前言我們在深入淺出面向?qū)ο蠛驮透拍钇谶@篇文章中了解到了如何使用解決重復(fù)創(chuàng)建浪費內(nèi)存的問題,其中的關(guān)鍵就是,那么這篇文章讓我們來重新了解的前世今生一個苦逼年級主任的故事開學(xué)啦高一年級主任龔主任需要為全年級每一位理科班新生錄入學(xué)號并為每一位 前言 我們在深入淺出面向?qū)ο蠛驮汀靖拍钇?】在這篇文章中了解到了如何使用new Function解決重復(fù)創(chuàng)建浪費內(nèi)存的問題,其中的關(guān)鍵就是new...
摘要:首先,需要來理清一些基礎(chǔ)的計算機編程概念編程哲學(xué)與設(shè)計模式計算機編程理念源自于對現(xiàn)實抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機制一直以來都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因為絕大多數(shù)人沒有想要深刻理解這個機制的內(nèi)涵,以及越來越多的開發(fā)者缺乏計算機編程相關(guān)的基礎(chǔ)知識。對于這樣的開發(fā)者來說 J...
摘要:對象重新認(rèn)識面向?qū)ο竺嫦驅(qū)ο髲脑O(shè)計模式上看,對象是計算機抽象現(xiàn)實世界的一種方式。除了字面式聲明方式之外,允許通過構(gòu)造器創(chuàng)建對象。每個構(gòu)造器實際上是一個函數(shù)對象該函數(shù)對象含有一個屬性用于實現(xiàn)基于原型的繼承和共享屬性。 title: JS對象(1)重新認(rèn)識面向?qū)ο? date: 2016-10-05 tags: JavaScript 0x00 面向?qū)ο?從設(shè)計模式上看,對象是...
閱讀 1677·2021-11-22 09:34
閱讀 1737·2019-08-29 16:36
閱讀 2723·2019-08-29 15:43
閱讀 3162·2019-08-29 13:57
閱讀 1353·2019-08-28 18:05
閱讀 1940·2019-08-26 18:26
閱讀 3306·2019-08-26 10:39
閱讀 3510·2019-08-23 18:40