真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

JavaScript的繼承和原型鏈?zhǔn)鞘裁?/h1>

小編給大家分享一下JavaScript的繼承和原型鏈?zhǔn)鞘裁?,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿(mǎn)足客戶(hù)于互聯(lián)網(wǎng)時(shí)代的仁和網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

一、前言

JavaScript的繼承和原型鏈?zhǔn)俏以趯W(xué)習(xí)前端過(guò)程中遇到的較為少有的難以理解的部分,這里便將我所有知道和了解到的東西記錄了下來(lái)

二、構(gòu)造函數(shù)

2.1 構(gòu)造函數(shù)的實(shí)例成員和靜態(tài)成員

構(gòu)造函數(shù)由實(shí)例成員和靜態(tài)成員二者組成,其中實(shí)例成員是在函數(shù)內(nèi)部通過(guò)this關(guān)鍵字添加的成員;只能通過(guò)實(shí)例化對(duì)象以后通過(guò)實(shí)例化對(duì)象進(jìn)行訪(fǎng)問(wèn);而靜態(tài)成員是函數(shù)本身上添加的成員,只能通過(guò)構(gòu)造函數(shù)來(lái)訪(fǎng)問(wèn)。

//創(chuàng)造一個(gè)構(gòu)造函數(shù)let Father = function(name,age){
    //實(shí)例成員
    this.name = name;
    this.age = age;
    this.method = "我是一個(gè)實(shí)例成員";}
    //靜態(tài)成員Father.like = "mother";
    //檢驗(yàn)實(shí)例對(duì)象是否能夠被構(gòu)造函數(shù)直接訪(fǎng)問(wèn)console.log(Father.method);
    //undefinedconsole.log(Father.like);
    //mother
    //實(shí)例化一個(gè)對(duì)象let father = new Father("小王",27);
    //檢驗(yàn)靜態(tài)對(duì)象是否能夠被實(shí)例化對(duì)象訪(fǎng)問(wèn)console.log(father.name);
    //小王console.log(father.age);
    //27console.log(father.like);
    //undefined
2.2 實(shí)例化對(duì)象的過(guò)程

通過(guò)new關(guān)鍵字可以通過(guò)構(gòu)造函數(shù)實(shí)現(xiàn)一個(gè)實(shí)例化對(duì)象,那么在具體實(shí)例化的過(guò)程中發(fā)生了什么呢?大致可以劃分為以下幾個(gè)步驟:

(1) 創(chuàng)建一個(gè)空對(duì)象 son {}

(2) 為 son 準(zhǔn)備原型鏈連接 son.__proto__ = Father.prototype

(3) 重新綁定this,使構(gòu)造函數(shù)的this指向新對(duì)象 Father.call(this)

(4) 為新對(duì)象屬性賦值 son.name

(5) 返回this return this,此時(shí)的新對(duì)象就擁有了構(gòu)造函數(shù)的方法和屬性了

一個(gè)小問(wèn)題:所有實(shí)例化對(duì)象的方法都是共享的嗎?

構(gòu)造函數(shù)的方法分為兩種,第一種為在函數(shù)內(nèi)部直接定義的方法,第二種為通過(guò)原型添加的方法;

//函數(shù)內(nèi)部直接定義的方法let Father = function(){
    this.read = function(){
        console.log("我是內(nèi)部定義的read方法!");
    }}//通過(guò)原型鏈添加的方法Father.prototype.look = function(){
    console.log("我是通過(guò)原型鏈定義的look方法!");}
    //實(shí)例化對(duì)象進(jìn)行檢驗(yàn)let father1 = new Father();let father2 = new Father();
    father1.read();
    //我是內(nèi)部定義的read方法!father2.read();
    //我是內(nèi)部定義的read方法!console.log(father1.read === father2.read);
    //falsefather1.look();
    //我是通過(guò)原型鏈定義的look方法!father2.look();
    //我是通過(guò)原型鏈定義的look方法!console.log(father1.look === father2.look);
    /true

可以發(fā)現(xiàn),函數(shù)內(nèi)部直接定義的方法在每實(shí)例化一個(gè)新的對(duì)象以后,都會(huì)給這個(gè)方法分配一個(gè)新的內(nèi)存空間,而通過(guò)原型添加的方法便會(huì)共享一個(gè)空間。

一個(gè)小問(wèn)題:所有實(shí)例化對(duì)象的屬性都是共享的嗎?

不存在內(nèi)存空間的問(wèn)題,判斷時(shí)看其值是否相同;

let Father = function(name){
    this.name = name;}let father1 = new Father("小王");
    let father2 = new Father("小紅");
    console.log(father1.name === father2.name);
    //falselet father1 = new Father("小王");
    let father2 = new Father("小王");
    console.log(father1.name === father2.name);
    //true

因此我們可以總結(jié)一下定義構(gòu)造函數(shù)的基本規(guī)則,即公共屬性定義到構(gòu)造函數(shù)里面,公共方法我們放到原型對(duì)象身上。

三、原型

3.1 什么是原型

Father.prototype 就是原型,它是一個(gè)對(duì)象,也可以稱(chēng)為原型對(duì)象。

3.2 原型的作用是什么

原型的作用,就是共享方法。

我們通過(guò) Father.prototype.method 可以共享方法,不會(huì)反應(yīng)開(kāi)辟空間存儲(chǔ)方法。

3.3 原型中的this指向哪兒

原型中this的指向是實(shí)例。

四、原型鏈

原型鏈本人感覺(jué)是一個(gè)對(duì)于初學(xué)者或者說(shuō)是部分前端菜雞(例如本人)來(lái)說(shuō)特別難以理解的東西,為了讓下面的部分更容易理解,這里強(qiáng)行先記住以下幾點(diǎn):

  1. __proto__是每個(gè)對(duì)象都有的屬性,prototype是每個(gè)函數(shù)特有的方法;

  2. 每個(gè)對(duì)象的__proto__屬性都會(huì)指向自身構(gòu)造函數(shù)的prototype;

  3. constructor屬性始終指向創(chuàng)建當(dāng)前對(duì)象的構(gòu)造函數(shù);

  4. Function.__proto__ === Function.prototype;

  5. Object.prototype.__proto__ === null 也就是原型鏈的終點(diǎn);

4.1 什么是原型鏈

原型與原型層層相鏈接的過(guò)程即為原型鏈。

4.2 原型鏈的應(yīng)用

對(duì)象可以使用構(gòu)造函數(shù)prototype原型對(duì)象的屬性和方法,就是因?yàn)閷?duì)象有__proto__原型的存在每個(gè)對(duì)象都有__proto__原型的存在

let Father = function(name){
    this.name = name;}let father = new Father("老王");console.log(father.__proto__ === Father.prototype);
    //true
    //驗(yàn)證上述說(shuō)法中的第二條
4.3 原型鏈圖

JavaScript的繼承和原型鏈?zhǔn)鞘裁?></p><p>結(jié)合寫(xiě)在最前面的幾點(diǎn),理解上圖應(yīng)該問(wèn)題不大了,圖中圈起來(lái)的部分就是駭人聽(tīng)聞的原型鏈。</p><h5>4.4 原型鏈的查找方式</h5><pre>function Star(name) {
	this.name = name;
	//(1)首先看obj對(duì)象身上是否有dance方法,如果有,則執(zhí)行對(duì)象身上的方法
	this.dance = function () {
		console.log(this.name + '1');
	}}//(2)如果沒(méi)有dance方法,就去構(gòu)造函數(shù)原型對(duì)象prototype身上去查找dance這個(gè)方法。Star.prototype.dance = function () {
	console.log(this.name + '2');};
	//(3)如果再?zèng)]有dance方法,就去Object原型對(duì)象prototype身上去查找dance這個(gè)方法。Object.prototype.dance = function () {
	console.log(this.name + '3');};
	//(4)如果再?zèng)]有,則會(huì)報(bào)錯(cuò)。let obj = new Star('小紅');obj.dance();</pre><p>(1)首先看obj對(duì)象身上是否有dance方法,如果有,則執(zhí)行對(duì)象身上的方法。</p><p>(2)如果沒(méi)有dance方法,就去構(gòu)造函數(shù)原型對(duì)象prototype身上去查找dance這個(gè)方法。</p><p>(3)如果再?zèng)]有dance方法,就去Object原型對(duì)象prototype身上去查找dance這個(gè)方法。</p><p>(4)如果再?zèng)]有,則會(huì)報(bào)錯(cuò)。</p><h6>一個(gè)小問(wèn)題:在原型上添加方法需要注意的地方</h6><p>有兩種添加方法,第一種為上面的寫(xiě)法,直接通過(guò) 構(gòu)造函數(shù).prototype.方法名 進(jìn)行添加;第二種為重定義構(gòu)造函數(shù)的prototype,但是此種情況會(huì)丟失掉原有的constructor構(gòu)造器,所以一定要再連接回去,例子如下:</p><pre>function Star(name) {
	this.name = name;}Star.prototype = {
    dance:function(){
    	console.log(

另外,類(lèi)似于A(yíng)rray、String這些內(nèi)置的類(lèi)是不能這么處理的。

五、繼承

這里就長(zhǎng)話(huà)短說(shuō),首先我們要明確繼承需要繼承哪些東西,在前文中我們提到了定義構(gòu)造函數(shù)的基本規(guī)則,即**公共屬性定義到構(gòu)造函數(shù)里面,公共方法我們放到原型對(duì)象身上。**我們所需要繼承的東西也不外乎就這二者,公共屬性的繼承可以通過(guò)call()或者apply()進(jìn)行this的指向定義,而公共方法可以通過(guò)原型對(duì)象的賦值進(jìn)行處理,因此我們很容易想到如下的方法:

//定義一個(gè)父類(lèi)function Father(name) {
	this.name = name;}Father.prototype.dance = function () {
	console.log('I am dancing');};//定義一個(gè)子類(lèi)function Son(name, age) {
	Father.call(this, name);
	this.age = age;}//通過(guò)賦值的方法連接Son.prototype = Father.prototype;//為子類(lèi)添加方法Son.prototype.sing = function () {
	console.log('I am singing');};
	let son = new Son('小紅', 100);
	//此時(shí)父類(lèi)也被影響了console.log(Father.prototype) 
	//{dance: ?, sing: ?, constructor: ?}

很顯然,當(dāng)我們只想修改子類(lèi)里面的方法時(shí),顯然上述方法不太合適;因此 我們可以嘗試new一個(gè)新的父類(lèi)出來(lái),代碼如下:

function Father(name) {
	this.name = name;}Father.prototype.dance = function () {
	console.log('I am dancing');};function Son(name, age) {
	Father.call(this, name);
	this.age = age;}Son.prototype = new Father();Son.prototype.sing = function () {
	console.log('I am singing');};let son = new Son('小紅', 100);console.log(Father.prototype) 
	//{dance: ?, constructor: ?}

六、class語(yǔ)法糖

對(duì)于以前了解過(guò)面向?qū)ο缶幊痰某绦騿T來(lái)講,上述關(guān)于繼承的寫(xiě)法屬實(shí)讓人有些難以接受,因此在es6里面新增了一個(gè)語(yǔ)法糖來(lái)更方便更便捷地書(shū)寫(xiě)繼承,這里就直接上代碼了;

class Father {
	constructor(name) {
		this.name = name;
	}
	dance() {
		console.log("我是" + this.name + ",我今年" + this.age + "歲," + "我在跳舞");
	}}class Son extends Father {
	constructor(name, age) {
		super(name);
		this.age = age;
	}
	sing() {
		console.log("我是" + this.name + ",我今年" + this.age + "歲," + "我在唱歌");
	}}let obj = new Son('小紅', 19);
	obj.sing();obj.dance();

分析一下上面代碼,首先一個(gè)類(lèi)(構(gòu)造函數(shù))里面依舊為兩部分,即公共屬性和公共方法,constructor()里面存放了該構(gòu)造函數(shù)的公共屬性,后面接著的便是公共方法,extends關(guān)鍵字表示繼承的是哪個(gè)類(lèi),super()便是將里面父類(lèi)里面相應(yīng)的公共屬性拿出來(lái),這樣看下來(lái)便可以將代碼規(guī)整許多。

以上是“JavaScript的繼承和原型鏈?zhǔn)鞘裁础边@篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


網(wǎng)站欄目:JavaScript的繼承和原型鏈?zhǔn)鞘裁?
文章轉(zhuǎn)載:http://weahome.cn/article/ihdioh.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部