摘要:原型與原型鏈一在了解原型之前需要提前了解的。構(gòu)造函數(shù)能很好的解決這個(gè)問題。構(gòu)造函數(shù)自定義構(gòu)造函數(shù),可以自定義對(duì)象類型的屬性和方法。二原型模式如下,與構(gòu)造函數(shù)模式不同的是,原型模式的每個(gè)實(shí)例都是訪問同一屬性同一函數(shù),,函數(shù)不用重新創(chuàng)建。
原型與原型鏈
一.在了解原型之前需要提前了解的。
1.工廠模式:創(chuàng)建一個(gè)函數(shù),用特定的接口創(chuàng)建對(duì)象的細(xì)節(jié)。
//現(xiàn)在要?jiǎng)?chuàng)建兩個(gè)包含 “name”和“age”的對(duì)象, let tom ={name:"Tom",age:16} let lily = { name : "Lily",age:18} ……//所示數(shù)量足夠具大 ,對(duì)象足夠大 ,會(huì)花費(fèi)大量的時(shí)間。下面的工廠模式能 很好的解決這一問題
//工廠的就是只流水線不是所有都是要人工,節(jié)約人力成本。 function person(name,age){ let obj = {}; //創(chuàng)建一個(gè)對(duì)象 ; obj.name = name ; //為對(duì)象添加細(xì)節(jié) obj.age = age ; obg.sayHello= function (){ alert ("Hello"+this.name) }; return obj;} //返回這個(gè)對(duì)象 let tom = person("Tom",16); let lily = person("Lily",18)
工廠函數(shù)的優(yōu)勢(shì):避免的大量的重復(fù)代碼;
工廠函數(shù)的劣勢(shì):其創(chuàng)建的對(duì)象不能標(biāo)志為一種特定的類型,沒有解決對(duì)象識(shí)別的問題,不知道對(duì)象的類型。構(gòu)造函數(shù)能很好的解決這個(gè)問題。
2.構(gòu)造函數(shù):自定義構(gòu)造函數(shù),可以自定義對(duì)象類型的屬性和方法。
function Person(name,age){ this.name = name ; //為對(duì)象添加細(xì)節(jié) this.age = age ; this.sayHello= function (){ alert ("Hello"+this.name) }; let tom = new Person("Tom",16); let lily =new Person("Lily",18)
new的過程做了三件事①創(chuàng)建了一個(gè)對(duì)象;②將this指向這個(gè)對(duì)象;③返回這個(gè)對(duì)象;
兩個(gè)實(shí)例對(duì)象都有一個(gè)屬性constructor(構(gòu)造函數(shù)),指向Person;這就是可以通過constructor判斷對(duì)象類型的原理。
存在的問題:構(gòu)造函數(shù)的每個(gè)方法都要在實(shí)例上重新創(chuàng)建一遍,雖然函數(shù)名是一樣的,但是不相等的。
二.原型模式
1.如下,與構(gòu)造函數(shù)模式不同的是,原型模式的每個(gè)實(shí)例都是訪問同一屬性同一函數(shù),,函數(shù)不用重新創(chuàng)建。
function Person () { this.x = 100; } Person.prototype.name = "Tom"; Person.prototype.age = 18; Person.prototype.sayHello = function (){ alert(`Hello${this.name}`) } let Tom = new Person() Tom.sayHello()
2.原型對(duì)象
①每個(gè)函數(shù)數(shù)據(jù)類型(普通函數(shù),類)上,都有一個(gè)屬性,叫prototype,是一個(gè)對(duì)象,這個(gè)函數(shù)指向函數(shù)的原型對(duì)象;
②prototype這個(gè)對(duì)象上,自帶一個(gè)屬性,constructor指向當(dāng)前這個(gè)類;
③當(dāng)為實(shí)例添加屬性時(shí),這個(gè)屬性會(huì)屏蔽原型對(duì)象中保存的同名屬性,但是事實(shí)阻止訪問,并沒有修改那個(gè)屬性,若將同名的實(shí)例屬性設(shè)置為null,同樣會(huì)屏蔽,但是若用delete,則可以刪除實(shí)例屬性,可以重新訪問原型中的屬性。
alert(Tom.age); //18 let Tom.age = 20; alert(Tom.age); //20 delete Tom.age; alert(Tom.age); //18
④屬性分為兩種,來自實(shí)例(或者是構(gòu)造函數(shù))或是原型,原型上的屬性和方法都是共有的,構(gòu)造函數(shù)中的屬性方法都是私有的,構(gòu)造函數(shù)中的this都是實(shí)例。為什么私有屬性(來自實(shí)例的屬性)的查找等級(jí)要高呢?這就涉及到原型鏈。
3.原型鏈:每個(gè)對(duì)象數(shù)據(jù)類型(普通對(duì)象,prototype,實(shí)例)都有一個(gè)屬性,叫做__proto__;
比如我們console.log(Tom.age)的查找過程是怎樣的呢?①首先在私有空間內(nèi)查找age屬性,私有空間的屬性包括自身的屬性和從類那里繼承的屬性,
②找不到的話:通過__proto__去當(dāng)前實(shí)例所屬類的原型上進(jìn)行查找,找到的話,說明是共有屬性;
③還找不到的話:繼續(xù)通過__proto__去當(dāng)前實(shí)例所屬類的原型進(jìn)行查找,找不到將繼續(xù)通過__proto__一直找到Object。
④曲線①代表Person的原型對(duì)象;曲線②中,實(shí)例Tom通過__proto__指向Tom所屬類(Person)的原型(Person Prototype);曲線③中,Person的原型對(duì)象通過__proto__找到Person對(duì)象的所屬類,也就是Object(函數(shù)也是對(duì)象類,萬物皆對(duì)象),指向它的原型(ObjectPrototype) ;曲線5中,指向Obeject所屬類的原型,它的類就是它自己,所以此時(shí)不在有__proto__整個(gè)屬性查找結(jié)束,這就是原型鏈的查找過程。
⑤通過hasOwnProperty來判斷屬性,這個(gè)方法就是通過④中的查找過程,在基類Object中找到的。 判斷屬性是否在對(duì)象上“name” in Tom,其中in的查找過程也是通過上述的查找過程。
function hasPrototypeProperty(object,attr){ return !object.hasOwnProperty(attr) && (attr in object);}
4.關(guān)于原型需要注意的幾點(diǎn)
①使用簡單原型語法的時(shí)候,注意constructor的指向問題,
Person.prototype={ //此時(shí)constructor指向Object構(gòu)造函數(shù) name : "Tom", age:18 } Person.prototype={ //此時(shí)constructor指向Person constructor:Person, name : "Tom", age:18 }
②添加和修改原型的屬性和方法都能立即在所有對(duì)象實(shí)例中反應(yīng)出來(即使先創(chuàng)建實(shí)例后修改原型);但是如果重寫整個(gè)原型對(duì)象,創(chuàng)建在前的實(shí)例并不能獲得重寫后的屬性或方法。這是因?yàn)橹貙懺椭笫切律稍蛯?duì)象,和聲明在前的任何已經(jīng)存在的實(shí)例都沒有關(guān)系。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84318.html
摘要:原型鏈與繼承當(dāng)談到繼承時(shí),只有一種結(jié)構(gòu)對(duì)象。如果對(duì)該圖不怎么理解,不要著急,繼續(xù)往下看基于原型鏈的繼承對(duì)象是動(dòng)態(tài)的屬性包指其自己的屬性。當(dāng)使用操作符來作用這個(gè)函數(shù)時(shí),它就可以被稱為構(gòu)造方法構(gòu)造函數(shù)。 原型鏈與繼承 當(dāng)談到繼承時(shí),JavaScript 只有一種結(jié)構(gòu):對(duì)象。每個(gè)實(shí)例對(duì)象(object )都有一個(gè)私有屬性(稱之為proto)指向它的原型對(duì)象(prototype)。該原型對(duì)象也...
摘要:寫在前面如果說是一本武學(xué)典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術(shù)是從底層上去理解,那種工程師和碼農(nóng)的區(qū)別就在于對(duì)底層的理解,當(dāng)你寫完一行代碼,或者你遇見一個(gè)解決的速度取決于你對(duì)底層的理解。 寫在前面 如果說JavaScript是一本武學(xué)典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對(duì)九陽神功是這樣描述的:練成「九陽神功」后,會(huì)易筋洗髓;生出...
摘要:寫在前面如果說是一本武學(xué)典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術(shù)是從底層上去理解,那種工程師和碼農(nóng)的區(qū)別就在于對(duì)底層的理解,當(dāng)你寫完一行代碼,或者你遇見一個(gè)解決的速度取決于你對(duì)底層的理解。 寫在前面 如果說JavaScript是一本武學(xué)典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對(duì)九陽神功是這樣描述的:練成「九陽神功」后,會(huì)易筋洗髓;生出...
摘要:寫在前面如果說是一本武學(xué)典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術(shù)是從底層上去理解,那種工程師和碼農(nóng)的區(qū)別就在于對(duì)底層的理解,當(dāng)你寫完一行代碼,或者你遇見一個(gè)解決的速度取決于你對(duì)底層的理解。 寫在前面 如果說JavaScript是一本武學(xué)典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對(duì)九陽神功是這樣描述的:練成「九陽神功」后,會(huì)易筋洗髓;生出...
閱讀 2078·2023-04-25 17:48
閱讀 3590·2021-09-22 15:37
閱讀 2941·2021-09-22 15:36
閱讀 6008·2021-09-22 15:06
閱讀 1644·2019-08-30 15:53
閱讀 1431·2019-08-30 15:52
閱讀 716·2019-08-30 13:48
閱讀 1126·2019-08-30 12:44