摘要:首先定義空函數這個不用解釋,然后把這個空函數的原型指向為的原型,然后再把的原型指向這個新的對象,一個完美傳遞最后,在把原型的構造方法定義成華麗的轉身,結果如下結果還是不對,于是我又在大神的肩膀上墊了一下腳。
總是聽說面向對象,類,繼承,__proto__,prototype,constructor.......于是乎小整理一下。
首先說,JS里的繼承是怎么弄的呢?
首先創建類(Person)
var Person = { male: 0, age:0, name:"nothing", say:function(){ console.log("Hello World"); } }
如何創建一個人呢?
var createPerson = function(){ return Object.create(Person); }
創建學生
var Student = createPerson(); Student.say() //Hello World Student.__proto__ === Person //true Student.constructor === Person //Student的構造器還是Object
從這個可以看出什么呢?可以看出所謂的繼承,就是下面的代碼而已:
SSSSS.__proto__ = BBBBB
但是呢?也沒有prototype啥關系嘛,因為壓根就和他沒關系,好像也不太好,換一種寫法好了。
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!"); } }
繼續創建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 }
那好,再創建一個coder類
var Coder = new Person(); Coder.say(); //Hello world!
這個不錯嘛,這樣在想創建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
這樣得到了我們想要的結果,驗證一下繼承關系:
JSer instanceof Coder; //true htmler instanceof Coder;//true Coder instanceof Person;//false
這樣就不好了,為什么不是繼承關系呢?查看一下Coder情況如何?
Coder.__proto__ === Person.prototype; //false Coder.__proto__ //function () { [native code] }
看來問題就出在這里,寫一個中間函數補充一下?
var pass = function(child,parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }
為了實現這一點,參考道爺(就是發明JSON的那個道格拉斯)的代碼,中間對象可以用一個空函數F來實現,大神寫的代碼,就是特么讓人深思。
仔仔細細想了下,我個人是這么理解的。
首先定義空函數這個不用解釋,然后把這個空函數的原型指向為Parent的原型,然后再把Child的原型指向這個新的F對象,一個完美傳遞;
最后,在把Child原型的構造方法定義成Child;
華麗的轉身,結果如下:
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
結果還是不對,于是我又在大神的肩膀上墊了一下腳。
var pass = function(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.__proto__ = new F(); Child.__proto__.constructor = Child; }
結果就正確了......
又查了一下,總結一下:
所有的對象都有__proto__屬性,該屬性對應該對象的原型.
所有的函數對象都有prototype屬性,該屬性的值會被賦值給該函數創建的對象的_proto_屬性.
所有的原型對象都有constructor屬性,該屬性對應創建所有指向該原型的實例的構造函數.
函數對象和原型對象通過prototype和constructor屬性進行相互關聯.
雖說弄懂了些表面的東西,實際上最主要的原因還是沒明白,那就是原型鏈到底有什么用呢?
好了,以上就是今天總結的一些內容,希望相互學習幫助,能夠在未來更好的工作生活。
信息來源:
(↓相關一些對我幫助很大,Git的學習就是在這里看的,說的很詳細也很生動↓)
廖雪峰JavaScript教程
JS原型、原型鏈深入理解
深入分析js中的constructor 和prototype
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83121.html
摘要:中的和是一門很靈活的語言,尤其是。即然是面向對象的編程語言,那也是不可或缺的。在中,永遠指向的是他的調用者。定義是存在于實例化后對象的一個屬性,并且指向原對象的屬性。我們在擴展的時候,同時父類也會有對應的方法,這很顯然是一個很嚴重的問題。 javascript中的this和new javascript是一門很靈活的語言,尤其是function。他即可以以面向過程的方式來用,比如: f...
摘要:面向對象中有三大特征,封裝,繼承,多態。這不僅無法做到數據共享,也是極大的資源浪費,那么引入對象實例對象的屬性指向其構造函數,這樣看起來實例對象好像繼承了對象一樣。實例對象的原型指向其構造函數的對象構造器的指向。 前言 為什么說是再談呢,網上講解這個的博客的很多,我開始學習也是看過,敲過就沒了,自以為理解了就結束了,書到用時方恨少啊。實際開發中一用就打磕巴,于是在重新學習了之后分享出來...
摘要:前言我們在深入淺出面向對象和原型概念篇在這篇文章中了解到了如何使用解決重復創建浪費內存的問題,其中的關鍵就是,那么這篇文章讓我們來重新了解的前世今生一個苦逼年級主任的故事開學啦高一年級主任龔主任需要為全年級每一位理科班新生錄入學號并為每一位 前言 我們在深入淺出面向對象和原型【概念篇2】在這篇文章中了解到了如何使用new Function解決重復創建浪費內存的問題,其中的關鍵就是new...
摘要:首先,需要來理清一些基礎的計算機編程概念編程哲學與設計模式計算機編程理念源自于對現實抽象的哲學思考,面向對象編程是其一種思維方式,與它并駕齊驅的是另外兩種思路過程式和函數式編程。 JavaScript 中的原型機制一直以來都被眾多開發者(包括本人)低估甚至忽視了,這是因為絕大多數人沒有想要深刻理解這個機制的內涵,以及越來越多的開發者缺乏計算機編程相關的基礎知識。對于這樣的開發者來說 J...
摘要:對象重新認識面向對象面向對象從設計模式上看,對象是計算機抽象現實世界的一種方式。除了字面式聲明方式之外,允許通過構造器創建對象。每個構造器實際上是一個函數對象該函數對象含有一個屬性用于實現基于原型的繼承和共享屬性。 title: JS對象(1)重新認識面向對象 date: 2016-10-05 tags: JavaScript 0x00 面向對象 從設計模式上看,對象是...
閱讀 1598·2021-11-22 09:34
閱讀 1689·2019-08-29 16:36
閱讀 2668·2019-08-29 15:43
閱讀 3113·2019-08-29 13:57
閱讀 1296·2019-08-28 18:05
閱讀 1874·2019-08-26 18:26
閱讀 3241·2019-08-26 10:39
閱讀 3453·2019-08-23 18:40