欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Javascript的原型和原型鏈你了解嗎

 更新時間:2022年03月03日 16:27:31   作者:與宇宙對視  
這篇文章主要為大家詳細介紹了Javascript的原型和原型鏈,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

一、為什么要使用原型?怎樣去理解原型的出現(xiàn)

1、對象字面量創(chuàng)建對象的缺點

想要介紹原型,就不得不提為什么我們要使用原型,在js早期,我們創(chuàng)建一個對象,比較流行的做法是使用對象字面量去創(chuàng)建一個對象,例如:

const person = {
            name: "wywy",
            age: 21,
            hobby: "聽周杰倫"
}

用這種方式去創(chuàng)建對象,雖然簡潔明了,但是我們?nèi)绻枰笈康膭?chuàng)建這一類的對象,就像person這個對象,我們可能需要去創(chuàng)建多個不同的人,那么每一次都需要去聲明創(chuàng)建,這樣工作量是巨大的,為了解決這個問題我們引入了工廠函數(shù)的概念。

2、工廠函數(shù)

什么是工廠函數(shù),顧名思義就可以把工廠函數(shù)看作是一個流水線的工廠,這個工廠的作用就是批量生產(chǎn)person對象,就像下面這樣:

function createPerson(name,age,hobby){
	const obj = {};
	obj.name = name;
	obj.age = age;
	obj.hobby = hobby;
	return obj;
}
const person1 = createPerson("zs", 23, "滑板");
const person2 = createPerson("ls", 22, "聽歌");
console.log(person1);
console.log(person2);

在這里插入圖片描述

這里我們在創(chuàng)建person對象的時候只需要調(diào)用這個函數(shù)即可,并把每個對象對應(yīng)的屬性值傳入就好了,這樣相對于用對象字面量去創(chuàng)建一個個的person確實簡化了代碼量,但是工廠函數(shù)也有自身的缺點,就是我們不能去判斷出這個對象的類型,按我們知道的在 js 中復(fù)雜引用數(shù)據(jù)類型進行細分,有 Array,F(xiàn)unction,String 等,但是通過工廠函數(shù)模式創(chuàng)建的這些對象用控制臺打印去全部都是 Object 類型,假如你有多個工廠函數(shù),用多個工廠函數(shù)創(chuàng)建了多個實例,但是你卻并不知道這些對象屬于哪個工廠。為此又推出了構(gòu)造函數(shù)這個概念。

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

關(guān)于構(gòu)造函數(shù)其實它和工廠函數(shù)非常相似,在js的函數(shù)中其實并沒有單獨的一類函數(shù)叫做構(gòu)造函數(shù),構(gòu)造函數(shù)總是和new關(guān)鍵字一起使用,更準(zhǔn)確地說一個函數(shù)被構(gòu)造調(diào)用了。當(dāng)一個構(gòu)造函數(shù)不使用new關(guān)鍵字調(diào)用時,他和普通的函數(shù)無異。

function CreatePerson(name, age, hobby) {
            this.name = name;
            this.age = age;
            this.hobby = hobby;
}
const person1 = new CreatePerson("zs", 23, "滑板");
const person2 = new CreatePerson("ls", 22, "聽歌");
console.log(person1);
console.log(person2);

在這里插入圖片描述

仔細觀察,不難發(fā)現(xiàn)我們對上面的工廠函數(shù)進行了以下幾點改造:

1、我們將函數(shù)名的首字母大寫了,在 js 中有個規(guī)定如果你以后打算將一個函數(shù)作為構(gòu)造函數(shù)去使用那么最好把它的函數(shù)名首字母大寫,來提醒使用者這是一個構(gòu)造函數(shù)。其實不大寫也不會有什么語法錯誤。

2、我們?nèi)∠嗽诤瘮?shù)內(nèi)部顯示的聲明一個對象 “const obj = {}”,并一并取消了最后返回這個對象的操作 “return obj”。

3、在調(diào)用這個這個 CreatePerson 函數(shù)時在前面加上了 new 關(guān)鍵字。

在這里插入圖片描述

然后我們看這個結(jié)果,這個時候我們打印的對象不在是 Object 了,而是我們自己創(chuàng)建的函數(shù) CreatePerson??磥順?gòu)造函數(shù)確實解決了對象無法判定類型的問題。
那么神奇的new關(guān)鍵字在后臺做了什么呢?其實它做了下面的五件事

1、在內(nèi)存中創(chuàng)建一個新的對象。

2、讓新對象的內(nèi)部特性 [[Prototype]] 保存函數(shù) CreatePerson 的 prototype 的屬性值,也就是把函數(shù)的原型的指針保存到了 [[Prototype]] 中。

3、把函數(shù)內(nèi)部的 this 指向這個新創(chuàng)建的對象。

4、執(zhí)行函數(shù)內(nèi)部的代碼。

5、如果函數(shù)本身沒有返回對象,那么就把這個新對象返回。

我們看構(gòu)造函數(shù)原來在后臺為我們做了這么多事。那么構(gòu)造函數(shù)就完美了嗎?并不是的,我們想一個 person 是不是應(yīng)該也該給他加一個方法呢?那么我們就給加一個說話的方法吧:

function CreatePerson(name, age, hobby) {
     this.name = name;
     this.age = age;
     this.hobby = hobby;
     // 添加一個方法
     this.sayHi = function() {
         console.log("你好,我叫" + this.name)
     }
 }
const person1 = new CreatePerson("zs", 23, "滑板");
const person2 = new CreatePerson("ls", 22, "聽歌");
 console.log(person1);
 console.log(person2);

但是我們發(fā)現(xiàn)這樣做無疑為每一個實例對象都添加了一個 sayHi 方法,而且每個實例上的方法都不相等,但我們的目的是讓每個實例都有這么一個功能就好了,不必創(chuàng)建這么多的 sayHi 方法而去浪費內(nèi)存空間。說的直白一點,比如家里有五個孩子,每個孩子都想玩 switch 游戲,那么家長要給每個孩子買一臺 switch 嗎?當(dāng)然家里有礦的當(dāng)我沒說,一般家庭是不是就買一臺,然后哪個孩子想玩就管家長去要就行了是不是。

同樣的,代碼就是對現(xiàn)實生活的抽象,那么我們是不是也可以這樣做,把方法添加到這些實例都擁有的一個爸爸是不是就好了,而仔細想想在 new 的五步中第二步是不是做了這么一件事,沒錯他就是 js 中的原型。這個原型就是這些實例的爸爸。

說了這么多我們總算要講原形了!!!

二、使用原型

通過上面的講解我們似乎對原型的作用有了大致的理解,就是把實例對象上需要用到的共有方法添加到原型上,而實例對象的自己的私有屬性寫在構(gòu)造函數(shù)內(nèi)部。
接下來我們對構(gòu)造函數(shù)進行再一次改造:

function CreatePerson(name, age, hobby) {
     this.name = name;
     this.age = age;
     this.hobby = hobby;
     // 添加一個方法
     this.sayHi = function() {
         console.log("你好,我叫" + this.name)
     }
 }
const person1 = new CreatePerson("zs", 23, "滑板");
const person2 = new CreatePerson("ls", 22, "聽歌");
 console.log(person1);
 console.log(person2);

首先向大家說明一點我并沒有按著定義一個構(gòu)造函數(shù),然后在構(gòu)造函數(shù)的原型上添加 sayHi 方法,接著使用 new 創(chuàng)建實例的順序來寫代碼。而是先 new 創(chuàng)建了實例,然后再在原型上添加方法,這樣的目的是想告訴大家,原型是具有動態(tài)性的,即你先創(chuàng)建了實例,在實例之后給原型添加了方法那么實例依然是可以訪問的。而且可以看到通過比較 person1 和 person2 的 sayHi 方法我們發(fā)現(xiàn)這是同一個方法。這樣我們完美的解決了構(gòu)造函數(shù)的問題。

三、原型概念辨析

首先清楚兩個概念:

  • 引用類型,都具有對象特性,即可自由擴展屬性。(引用類型:Object、Array、Function、Date、RegExp)
  • 每個函數(shù)function都有一個顯示原型prototype,每個實例對象都有一個隱式原型__proto__
function Fn() { // 內(nèi)部語句:this.prototype = {}
}
// 1、每個函數(shù)function都有一個prototype,即顯示原型(屬性)
console.log(Fn.prototype);
// 2、每個實例對象都有一個__proto__,可稱為隱式原型(屬性)
var fn = new Fn(); // 內(nèi)部語句: this.__proto__ = Fn.prototype
console.log(fn.__proto__);

兩個準(zhǔn)則:

在設(shè)計js原型原型鏈的時候遵循以下兩個準(zhǔn)則:

準(zhǔn)則一: 原型對象(即Fn.prototype)的 constructor 指向構(gòu)造函數(shù)本身。

準(zhǔn)則二: 實例對象(即 fn )的__proto__ 指向其構(gòu)造函數(shù)的顯示原型。

function Fn() {}
var fn = new Fn();
// 原型對象的 constructor 指向構(gòu)造函數(shù)本身
console.log(Fn.prototype.constructor === Fn); // true
// 對象的隱式原型的值為其對應(yīng)構(gòu)造函數(shù)的顯示原型的值
console.log(Fn.prototype === fn.__proto__); // true

理解Function與Object特例

每個函數(shù)都是 Function 的實例,所以每個函數(shù)既有顯示原型又有隱式原型,所有函數(shù)的隱式原型指向 Function.prototype; 構(gòu)造器Function的構(gòu)造器是它自身。

// function Foo() {} 相當(dāng)于 var Foo = new Function()
// Function = new Function() => Function.__proto__ = Function.prototype
// Object 作為構(gòu)造函數(shù)時,其 __proto__ 內(nèi)部屬性值指向 Function.prototype
// Object.__proto__ = Function.prototype
// Function.constructor=== Function;//true

Object構(gòu)造函數(shù)創(chuàng)建一個對象包裝器。JavaScript中的所有對象都來自 Object,所有對象都是Object的實例;所有對象從Object.prototype繼承方法和屬性,盡管它們可能被覆蓋。

// Fn的原型對象(Fn.prototype)也來自O(shè)bject,故Fn.prototype.__proto__ = Object.prototype
function Fn() {}

原型鏈:

讀取某個對象的屬性時,會自動找到原型鏈中查找。

  • 1、現(xiàn)在自身屬性中查找,找到返回
  • 2、找不到則繼續(xù)沿著__proto__這條鏈向上查找,找到返回
  • 3、如果最終沒有找到。返回undefined設(shè)置對象的屬性值時,不會查找原型鏈,如果當(dāng)前對象中沒有此屬性,直接添加此屬性并設(shè)置其值方法一般定義在原型中,屬性一般通過構(gòu)造函數(shù)定義在對象本身

原型鏈就是一個過程,原型是原型鏈這個過程中的一個單位,貫穿整個原型鏈

圖解

在這里插入圖片描述

四、原型鏈練習(xí)

//練習(xí)題1
function A(){
}
A.prototype.n = 1;
var b = new A();
A.prototype = {
	n:2,
	m:3
}
var c = new A();
console.log(b.n,b.m,c.n,c.m)
// 1 undefined 2 3
// 測試題2
var F = function() {
};
Object.prototype.a = function() {
    console.log('a()');
};
Function.prototype.b = function() {
    console.log('b()');
};
var f = new F();
f.a(); // a()
f.b(); // 報錯:Uncaught TypeError: f.b is not a function
F.a(); // a()
F.b(); // b()

原型、原型鏈的意義與使用場景:

原型對象的作用,是用來存放實例中共有的那部分屬性、方法、可以大大減少內(nèi)存消耗。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!       

相關(guān)文章

  • 詳解Javascript?基于長連接的服務(wù)框架問題

    詳解Javascript?基于長連接的服務(wù)框架問題

    本文針對經(jīng)常使用長連接進行消息收發(fā)的應(yīng)答場景,采用 Websocket 長連接作為服務(wù)監(jiān)聽的對象,模擬了一套類 http 服務(wù)框架,通過實例代碼介紹了Javascript?基于長連接的服務(wù)框架,需要的朋友可以參考下
    2022-07-07
  • 微信小程序配置服務(wù)器提示驗證token失敗的解決方法

    微信小程序配置服務(wù)器提示驗證token失敗的解決方法

    這篇文章主要介紹了微信小程序配置服務(wù)器提示驗證token失敗的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • 淺談Javascript事件模擬

    淺談Javascript事件模擬

    事件是用來描述網(wǎng)頁中某一特定有趣時刻的,眾所周知事件通常是在由用戶和瀏覽器進行交互時觸發(fā),其實不然,通過Javascript可以在任何時間觸發(fā)特定的事件,并且這些事件與瀏覽器創(chuàng)建的事件是相同的
    2012-06-06
  • 簡單的郵箱登陸的提示效果類似于yahoo郵箱

    簡單的郵箱登陸的提示效果類似于yahoo郵箱

    類似于yahoo郵箱登陸的提示效果,當(dāng)鼠標(biāo)聚焦到郵箱地址文本框時,文本框文字被清空
    2014-02-02
  • 一文詳解GoJs中g(shù)o.Panel的itemArray屬性

    一文詳解GoJs中g(shù)o.Panel的itemArray屬性

    這篇文章主要為大家介紹了一文詳解GoJs中g(shù)o.Panel的itemArray屬性詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • JavaScript鍵盤事件常見用法實例分析

    JavaScript鍵盤事件常見用法實例分析

    這篇文章主要介紹了JavaScript鍵盤事件常見用法,簡單描述了javascript鍵盤事件的分類、功能,并結(jié)合實例形式給出了javascript響應(yīng)鍵盤事件相關(guān)使用技巧,需要的朋友可以參考下
    2019-01-01
  • Bootstrap table學(xué)習(xí)筆記(2) 前后端分頁模糊查詢

    Bootstrap table學(xué)習(xí)筆記(2) 前后端分頁模糊查詢

    這篇文章主要為大家分享了Bootstrap table學(xué)習(xí)筆記,前后端分頁模糊查詢,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 類似CSDN圖片切換效果腳本

    類似CSDN圖片切換效果腳本

    原來的腳本當(dāng)只有一張圖片時會彈出JavaScript腳本錯誤,特此將自己修改完的版本貼出。
    2009-09-09
  • js設(shè)計模式之代理模式及訂閱發(fā)布模式實例詳解

    js設(shè)計模式之代理模式及訂閱發(fā)布模式實例詳解

    這篇文章主要介紹了js設(shè)計模式之代理模式及訂閱發(fā)布模式,結(jié)合實例形式詳細分析了代理模式及訂閱發(fā)布模式的概念、原理、實現(xiàn)方法及相關(guān)操作注意事項,需要的朋友可以參考下
    2019-08-08
  • js中的循環(huán)方式及各種遍歷的方法

    js中的循環(huán)方式及各種遍歷的方法

    本文主要介紹了js中的循環(huán)方式及各種遍歷的方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評論