成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

《javascript高級(jí)程序設(shè)計(jì)》筆記:原型圖解

vspiders / 572人閱讀

摘要:不理解沒關(guān)系,下面會(huì)結(jié)合圖例分析上一篇高級(jí)程序設(shè)計(jì)筆記創(chuàng)建對(duì)象下一篇高級(jí)程序設(shè)計(jì)筆記繼承參考之原型鏈的解讀三張圖搞懂的原型對(duì)象與原型鏈繼承與原型鏈

文章直接從原型圖解開始的,如果對(duì)一些概念不太清除,可以結(jié)合后面幾節(jié)查看
1. 圖解原型鏈 1.1 “鐵三角關(guān)系”(重點(diǎn))
function Person() {};
var p = new Person();

這個(gè)圖描述了構(gòu)造函數(shù),實(shí)例對(duì)象和原型三者之間的關(guān)系,是原型鏈的基礎(chǔ):
(1)實(shí)例對(duì)象由構(gòu)造函數(shù)new產(chǎn)生;
(2)構(gòu)造函數(shù)的原型屬性實(shí)例對(duì)象的原型對(duì)象均指向原型
(3)原型對(duì)象中有一個(gè)屬性constructor指向?qū)?yīng)的構(gòu)造函數(shù)

原型鏈:p --> Person.prototype
描述:實(shí)例對(duì)象能夠訪問到 Person.prototype 中不同名的屬性和方法
驗(yàn)證:

p instanceof Person; // true
  
p.__proto__ === Person.prototype; // true
  
Person.prototype.constructor === Person; // true
1.2 以原型為構(gòu)造函數(shù)

原型鏈:p --> Person.prototype --> Object.prototype --> null
描述:
(1)由于構(gòu)造函數(shù)的原型也是對(duì)象,因此:它也有原型對(duì)象,指向Object.__proto__
(2)由于構(gòu)造函數(shù)的原型的原型也是對(duì)象,因此:它也有原型對(duì)象,指向null(特例)
驗(yàn)證:

p instanceof Person; // true
p instanceof Object; // true
 
Person.prototype instanceof Object; // true
1.3 深入研究,引出Function構(gòu)造函數(shù)

1、原型鏈1:見1.2中的原型

2、原型鏈2:Person --> Function.prototype --> Object.prototype --> null
描述:
(1)構(gòu)造函數(shù)Person作為實(shí)例對(duì)象時(shí),Person = new Function()隱式調(diào)用,因此Person --> Function.prototype
(2)由于Function.prototype也是對(duì)象,Function.prototype = new Object()隱式調(diào)用,因此Function.prototype --> Object.prototype
驗(yàn)證:

Person instanceof Function; // true
Person instanceof Object; // true
Function.prototype instanceof Object; // true

3、原型鏈3:Function --> Function.prototype --> Object.prototype --> null
描述:
構(gòu)造函數(shù)Function作為實(shí)例對(duì)象時(shí),Function = new Function()隱式調(diào)用,因此Function --> Function.prototype

Function 這條原型鏈?zhǔn)亲顬樘厥獾摹拌F三角關(guān)系”,理解Function = new Function()就非常好理解了
驗(yàn)證:

Function.__proto__ === Function.prototype; // true
Function instanceof Function; // true
Function instanceof Object; // true
1.4 完整的原型鏈


圖中新增了Object = new Function()的邏輯

驗(yàn)證:

Object instanceof Function;// true

幾個(gè)結(jié)論:
(1)對(duì)象都有原型對(duì)象,對(duì)象默認(rèn)繼承自其原型對(duì)象
(2)所有的函數(shù)都是 Function 的實(shí)例
(3)所有的原型鏈尾端都會(huì)指向Object.prototype

下面提幾個(gè)問題:
(1)上圖有幾條原型鏈?分別列出來(上面已給出)
(2)如何在代碼層面驗(yàn)證原型鏈上的繼承關(guān)系?(見第四節(jié))
(3)圖中有幾個(gè)“鐵三角”關(guān)系?分別列出來

2. 原型鏈改寫(重點(diǎn))
當(dāng)實(shí)例對(duì)象被創(chuàng)建時(shí),其原型鏈就已經(jīng)確定了,當(dāng)其對(duì)應(yīng)的原型屬性指向改變時(shí),也無法改變?cè)玩?/pre>
function Person({name="小A", age=21}={}) {
  this.name = name;
  this.age = age;
};

// 情況1:在修改原型屬性前實(shí)例化對(duì)象
var p1 = new Person();

// 添加原型屬性(方法)
Person.prototype.sayName = function() {
  console.log(this.name);
}
// Person.prototype.SayHi = function() {}

// 情況2:在修改原型屬性后實(shí)例化對(duì)象
var p2 = new Person();

p1.sayName(); // "小A"
p2.sayName(); // "小A"

實(shí)例對(duì)象p1和實(shí)例對(duì)象p2的原型鏈相同,為 p1(p2) --> Person.prototype --> Object.prototype
=> 由于是在原有原型對(duì)象上添加的方法,相當(dāng)于對(duì)象的擴(kuò)展,故兩個(gè)實(shí)例對(duì)象均能執(zhí)行該方法

function Person({name="小A", age=21}={}) {
  this.name = name;
  this.age = age;
};

// 情況1:在修改原型屬性前實(shí)例化對(duì)象
var p1 = new Person();

// 重寫原型對(duì)象
Person.prototype = {
  sayName: function() {
    console.log(this.name);
  }
}

// 情況2:在修改原型屬性后實(shí)例化對(duì)象
var p2 = new Person();

p2.sayName(); // "小A"
p1.sayName(); // p1.sayName is not a function

重寫原型對(duì)象的方式,會(huì)改變實(shí)例對(duì)象的原型鏈,如下圖所示:

但是,為什么p1的原型鏈沒有變,而p2的原型鏈變了呢?

當(dāng)實(shí)例對(duì)象被創(chuàng)建時(shí),其原型鏈就已經(jīng)確定了,當(dāng)其對(duì)應(yīng)的原型屬性指向改變時(shí),也無法改變?cè)玩?/strong>
原型鏈?zhǔn)且詫?shí)例對(duì)象為核心的,不能被原型對(duì)象的改變而誤導(dǎo)

重寫原型對(duì)象的方式會(huì)在原型鏈繼承中經(jīng)常使用到?。?!

3. 對(duì)象與函數(shù)(重點(diǎn))

看到這里,我們可能已經(jīng)分不清函數(shù)與對(duì)象了,思考30秒,函數(shù)與對(duì)象是什么關(guān)系?

官方定義: 在Javascript中,每一個(gè)函數(shù)實(shí)際上都是一個(gè)函數(shù)對(duì)象
function fn() {};
var obj = {};

fn instanceof Object; // true
fn instanceof Function; // true

obj instanceof Object; // true
obj instanceof Function; // false

原型鏈解釋:
fn對(duì)應(yīng)的原型鏈:fn --> Function.prototype --> Object.prototype
obj對(duì)應(yīng)的原型鏈:obj --> Object.prototype

從函數(shù)的定義來說: 在javascript中一切函數(shù)實(shí)際都是函數(shù)對(duì)象,但對(duì)象不一定是函數(shù)

Function instanceof Object; // true
Object instanceof Function; // true

Function instanceof Function; // true

原型鏈解釋:
Function對(duì)應(yīng)的原型鏈(Function作為實(shí)例對(duì)象):Function --> Function.prototype --> Object.prototype
Object對(duì)應(yīng)的原型鏈(Object作為實(shí)例對(duì)象):Object --> Function.prototype --> Object.prototype

由于Function和Object都是構(gòu)造函數(shù),在內(nèi)置對(duì)象中,均會(huì)調(diào)用new Function()的方法

結(jié)論:
(1)函數(shù)一定是對(duì)象,但是對(duì)象不一定是函數(shù)
(2)對(duì)象都是由函數(shù)來創(chuàng)建的

針對(duì)第一點(diǎn),這兩個(gè)原型鏈可驗(yàn)證:
fn --> Function.prototype --> Object.prototype
obj --> Object.prototype

針對(duì)第二點(diǎn),可這樣驗(yàn)證:

var obj = { a: 1, b: 2}
var arr = [2, "foo", false]

// 實(shí)際過程
var obj = new Object()
obj.a = 1
obj.b = 2

var arr = new Array()
arr[0] = 2
arr[1] = "foo"
arr[2] = false

//typeof Object === "function"  
//typeof Array === "function
4. 幾個(gè)定義 4.1 原型的定義和作用
function Person() {};
var p = new Person();
構(gòu)造函數(shù)的prototype屬性的值(Person.prototype),也可以說成通過調(diào)用構(gòu)造函數(shù)而創(chuàng)建出來的那個(gè)實(shí)例對(duì)象的原型對(duì)象(p.__proto__)

只要是函數(shù)就有 prototype 屬性,即函數(shù)的原型屬性(由于對(duì)象是由函數(shù)創(chuàng)建的,因此對(duì)象也有prototype屬性)

函數(shù)的原型屬性也是對(duì)象(因此,這個(gè)對(duì)象也有對(duì)應(yīng)的prototype屬性)

由構(gòu)造函數(shù)創(chuàng)建出來的對(duì)象會(huì)默認(rèn)鏈接到其構(gòu)造函數(shù)的這個(gè)屬性上(constructor)

構(gòu)造函數(shù)的 prototype 屬性的作用是:實(shí)現(xiàn)數(shù)據(jù)共享(繼承)

4.2 幾個(gè)術(shù)語

實(shí)例對(duì)象中有一個(gè)屬性叫 __proto__ ,它是非標(biāo)準(zhǔn)屬性,指向構(gòu)造函數(shù)的原型屬性

Person.prototype 構(gòu)造函數(shù)的原型屬性
p.__proto__ 實(shí)例對(duì)象的原型對(duì)象

構(gòu)造函數(shù)的原型屬性實(shí)例對(duì)象的原型對(duì)象是一個(gè)東西,只是從不同的角度訪問原型

5. 屬性搜索原則和屬性來源判斷 5.1 屬性搜索原則(重點(diǎn))
當(dāng)代碼讀取某個(gè)對(duì)象的某個(gè)屬性時(shí),都會(huì)執(zhí)行一次搜索,目標(biāo)是具有給定名字的屬性。搜索先從對(duì)象實(shí)例本身開始,如果在實(shí)例中找到了具有給定名字的屬性,則返回該屬性的值;如果沒有找到,則繼續(xù)搜索指針指向的原型對(duì)象,在原型對(duì)象中查找具有給定名字的屬性。如果在原型對(duì)象中找到了這個(gè)屬性,則返回這個(gè)屬性,如果沒有找到,則繼續(xù)在這個(gè)原型對(duì)象的原型對(duì)象中查找,直到找到這個(gè)屬性,否則返回undefined

簡言之,沿著對(duì)象的原型鏈查找屬性,返回最近的屬性,這就是屬性搜索原則

function Person(){}

Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
  alert(this.name);
};

var person1 = new Person();
var person2 = new Person();

person1.name = "Greg";
alert(person1.name); //"Greg" 來自實(shí)例
alert(person2.name); //"Nicholas" 來自原型

同樣的,這也是屬性屏蔽的原則

// 接著上面的例子
delete person1.namel;
alert(person1.name); // "Nicholas" 來自原型
5.2 hasOwnProperty()方法與in操作符
使用hasOwnProperty()方法可以檢測一個(gè)屬性是存在于實(shí)例中,還是在原型中,這個(gè)方法只在給定屬性存在于對(duì)象實(shí)例中時(shí),才會(huì)返回true
function Person(){}

Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
  alert(this.name);
};

var person1 = new Person();
var person2 = new Person();

alert(person1.hasOwnProperty("name"));  //false

person1.name = "Greg";
alert(person1.name); //"Greg" 來自實(shí)例 
alert(person1.hasOwnProperty("name")); //true

alert(person2.name); //"Nicholas" 來自原型
alert(person2.hasOwnProperty("name")); //false

delete person1.name;
alert(person1.name); //"Nicholas" 來自原型
alert(person1.hasOwnProperty("name")); //false
有兩種方式使用in操作符:多帶帶使用和在for-in循環(huán)中使用。在多帶帶使用時(shí),in操作符會(huì)在通過對(duì)象能夠訪問給定屬性時(shí)返回true,無論該屬性存在于實(shí)例中還是原型中

因此,同時(shí)使用hasOwnProperty()和in操作符,就可以確定某個(gè)屬性到底是存在于對(duì)象中還是存在于原型中

function hasPrototypeProperty(object, name){
  return !object.hasOwnProperty(name) && (name in object);
}

順便一提,由于in操作符會(huì)在整個(gè)原型鏈上查找屬性,處于性能考慮,在使用for-in循環(huán)時(shí),建議多加一層判別

function Person(){}

Person.prototype.name = "Nicholas";
Person.prototype.age = 29;

var p = new Person();
p.sex = "fale";

for(key in p) {
  console.log(key); // sex name age 
}

// 實(shí)際上,我們一般只是在查找實(shí)例中的屬性
for(key in p) {
  if(p.hasOwnProperty(key)) {
    console.log(key); // sex 屏蔽了原型中的屬性
  }
}
5.3 instanceof操作符
instanceof 用來判斷一個(gè)構(gòu)造函數(shù)的prototype屬性所指向的對(duì)象是否存在另外一個(gè)要檢測對(duì)象的原型鏈上

更形象來說,對(duì)于 A instanceof B來說,它的判斷規(guī)則是:沿著A的__proto__這條線來找,同時(shí)沿著B的prototype這條線來找,如果兩條線能找到同一個(gè)引用,即同一個(gè)對(duì)象,那么就返回true。如果找到終點(diǎn)還未重合,則返回false。不理解沒關(guān)系,下面會(huì)結(jié)合圖例分析

function Person() {}
var p = new Person();
console.log(p instanceof Object);//true
console.log(p instanceof Person);//true

上一篇:《javascript高級(jí)程序設(shè)計(jì)》筆記:創(chuàng)建對(duì)象
下一篇:《javascript高級(jí)程序設(shè)計(jì)》筆記:繼承

參考:
JavaScript之原型鏈的解讀
三張圖搞懂JavaScript的原型對(duì)象與原型鏈
繼承與原型鏈

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/89571.html

相關(guān)文章

  • javascript高級(jí)程序設(shè)計(jì)筆記:繼承

    摘要:繼承和前面兩篇文章中的知識(shí)非常相關(guān),如果對(duì)函數(shù)創(chuàng)建原理和原型鏈不熟悉,請(qǐng)猛戳高級(jí)程序設(shè)計(jì)筆記創(chuàng)建對(duì)象高級(jí)程序設(shè)計(jì)筆記原型圖解繼承,通俗的說,就是將自身不存在的屬性或方法,通過某種方式為自己所用文章分別介紹原型鏈繼承繼承借用構(gòu)造函數(shù)繼承組合繼 繼承和前面兩篇文章中的知識(shí)非常相關(guān),如果對(duì)函數(shù)創(chuàng)建原理和原型鏈不熟悉,請(qǐng)猛戳:《javascript高級(jí)程序設(shè)計(jì)》筆記:創(chuàng)建對(duì)象《javascri...

    JerryC 評(píng)論0 收藏0
  • 《你不知道的javascript筆記_對(duì)象&原型

    摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響年是向上的一年在新的城市穩(wěn)定連續(xù)堅(jiān)持健身三個(gè)月早睡早起游戲時(shí)間大大縮減,學(xué)會(huì)生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響2018年是向上的一年:在新的城市穩(wěn)定、...

    seasonley 評(píng)論0 收藏0
  • javascript高級(jí)程序設(shè)計(jì)筆記:內(nèi)存與執(zhí)行環(huán)境

    摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當(dāng)我們?cè)诔绦蛑袆?chuàng)建一個(gè)對(duì)象時(shí),這個(gè)對(duì)象將被保存到運(yùn)行時(shí)數(shù)據(jù)區(qū)中,以便反復(fù)利用因?yàn)閷?duì)象的創(chuàng)建成本通常較大,這個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)就是堆內(nèi)存。 上一篇:《javascript高級(jí)程序設(shè)計(jì)》筆記:繼承近幾篇博客都會(huì)圍繞著圖中的知識(shí)點(diǎn)展開 showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...

    fuyi501 評(píng)論0 收藏0
  • 【5】JavaScript 函數(shù)高級(jí)——原型原型鏈深入理解(圖解

    摘要:探索是如何判斷的表達(dá)式如果函數(shù)的顯式原型對(duì)象在對(duì)象的隱式原型鏈上,返回,否則返回是通過自己產(chǎn)生的實(shí)例案例案例重要注意的顯示原型和隱式原型是一樣的。面試題測試題測試題報(bào)錯(cuò)對(duì)照下圖理解 原型與原型鏈深入理解(圖解) 原型(prototype) 函數(shù)的 prototype 屬性(圖) 每個(gè)函數(shù)都有一個(gè)prototype屬性,它默認(rèn)指向一個(gè)Object空對(duì)象(即稱為:原型對(duì)象) 原型對(duì)象中有...

    馬龍駒 評(píng)論0 收藏0
  • 【進(jìn)階2-1期】深入淺出圖解作用域鏈和閉包

    摘要:本期推薦文章從作用域鏈談閉包,由于微信不能訪問外鏈,點(diǎn)擊閱讀原文就可以啦。推薦理由這是一篇譯文,深入淺出圖解作用域鏈,一步步深入介紹閉包。作用域鏈的頂端是全局對(duì)象,在全局環(huán)境中定義的變量就會(huì)綁定到全局對(duì)象中。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第6天。 本...

    levius 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<