摘要:原型鏈只看構(gòu)造函數(shù)的原型對(duì)象和實(shí)例化出來(lái)的對(duì)象。既然構(gòu)造函數(shù)本身是函數(shù),那么和直接調(diào)用有什么區(qū)別答案揭曉只有通過(guò)調(diào)用構(gòu)造函數(shù)才會(huì)走第二步,也就是原型的委托操作。
原型
相信js開(kāi)發(fā)者都知道原型,原型鏈,但是很多人暈暈乎乎對(duì)此不知甚解。下面分享一下我的個(gè)人心得。
學(xué)習(xí)中的困惑構(gòu)造函數(shù),原型,實(shí)例對(duì)象之間的關(guān)系是什么?
原型鏈?zhǔn)窃趺蠢^承的?
既然構(gòu)造函數(shù)本身是函數(shù),那么new和直接調(diào)用有什么區(qū)別,
解答 構(gòu)造函數(shù),原型,實(shí)例對(duì)象之間的關(guān)系是什么?廢話不說(shuō)先上圖
不需要管網(wǎng)上亂七八糟的各種原型鏈指向圖,記住這個(gè)就行了。
除了各種指向以外,圖中還包含這些信息:
"prototype"屬性是函數(shù)獨(dú)有的
__proto__才是實(shí)例的。當(dāng)然,這個(gè)屬性不建議使用??梢杂?b>Object.setPrototypeOf和Object.getPrototypeOf
天真的我曾經(jīng)以為原型是prototype,那原型鏈就是跟著prototype找...,實(shí)在是too young too simple啊。
這里一定要記住,原型鏈?zhǔn)茄刂?b>__proto__鏈找。
其實(shí)這個(gè)問(wèn)題也可以是:當(dāng)我們構(gòu)建對(duì)象時(shí),發(fā)生了什么。
舉個(gè)簡(jiǎn)單例子:
function father(){ this.name = "爸爸" } father.prototype.family = "愛(ài)的家" var dad = new father();
這里進(jìn)行了如下操作:
實(shí)例化一個(gè)空對(duì)象Object.create();
將father的[[prototype]]屬性委托給father的原型。
指定上下文。即this為第一步實(shí)例化出來(lái)的空對(duì)象。
執(zhí)行構(gòu)造函數(shù)。
用代碼模擬就是:
function _new(/* 構(gòu)造函數(shù) */ constructor, /* 構(gòu)造函數(shù)參數(shù) */ param1) { // 將 arguments 對(duì)象轉(zhuǎn)為數(shù)組 var args = [].slice.call(arguments); // 取出構(gòu)造函數(shù) var constructor = args.shift(); // 創(chuàng)建一個(gè)空對(duì)象,繼承構(gòu)造函數(shù)的 prototype 屬性 var context = Object.create(constructor.prototype); // 執(zhí)行構(gòu)造函數(shù) var result = constructor.apply(context, args); // 如果返回結(jié)果是對(duì)象,就直接返回,則返回 context 對(duì)象 return (typeof result === "object" && result != null) ? result : context; } // 實(shí)例 var actor = _new(Person, "張三", 28);
記住一點(diǎn),實(shí)例化對(duì)象以后,構(gòu)造函數(shù)就沒(méi)什么事了。原型鏈只看構(gòu)造函數(shù)的原型對(duì)象和實(shí)例化出來(lái)的對(duì)象。
這里在說(shuō)一點(diǎn),關(guān)于,繼承?,F(xiàn)實(shí)中的繼承就是你的東西給我了,我拿過(guò)來(lái)了。我可以使用,可以轉(zhuǎn)讓。但是js中真是這樣嗎?
一個(gè)很簡(jiǎn)單的問(wèn)題,如果原型繼承真是把原型中的屬性拷過(guò)來(lái)那我每次自身找不到屬性還要沿著原型鏈查找干嘛。
很顯然,js中原型可不是二百五,他所謂的繼承,只是給你使用權(quán),不會(huì)給你轉(zhuǎn)讓權(quán)。
上面第二步中:將father的[[prototype]]屬性委托給father的原型。我寫(xiě)的是委托。這樣描述可能更準(zhǔn)確。因?yàn)檫@里只是相當(dāng)于給實(shí)例化對(duì)象一個(gè)指針,指向了原型對(duì)象。這其實(shí)也是下一個(gè)問(wèn)題的答案。
答案揭曉:
只有通過(guò)new調(diào)用構(gòu)造函數(shù)才會(huì)走第二步,也就是原型的委托操作。
那么怎么判斷是否同new調(diào)用呢?
ES6函數(shù)內(nèi)部可以使用new.target屬性。如果當(dāng)前函數(shù)是new命令調(diào)用,new.target指向當(dāng)前函數(shù),否則為undefined。
ES5
if(this instanceof Father){...}
ES6
//在函數(shù)外使用new.target是一個(gè)錯(cuò)誤 typeof new.target !== "undefined"
這里再多扯一下typeof和instance。反正我以前是每次看了記住了,很久不用又忘了。。。。,看了這么多原型鏈的內(nèi)容,再看看這個(gè)應(yīng)該會(huì)映象深刻吧:
typeof :用來(lái)判斷值類(lèi)型。如string/number/boolean,但如果判斷引用類(lèi)型,返回值就只有 object/function。所以無(wú)法進(jìn)一步判斷是object對(duì)象,還是數(shù)組,還是new Number等等。
注意:
undefined返回undefined。
// 錯(cuò)誤的寫(xiě)法 if (v) { // ... } // ReferenceError: v is not defined // 正確的寫(xiě)法 if (typeof v === "undefined") { // ... }instanceof :
根據(jù)原型鏈判斷引用類(lèi)型。A instanceof B,判斷原則是沿著 A 的__proto__這條線來(lái)找,同時(shí)沿著 B 的 prototype 這條線來(lái)找,如果兩條線能找到同一個(gè)引用,即同一個(gè)對(duì)象,那么就返回 true。如果找到終點(diǎn)還未重合,則返回 false。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/84986.html
摘要:高階函數(shù)不是的所特有的,其他編程語(yǔ)言也有。高階函數(shù)面向切面編程面向切面編程這種思想在開(kāi)發(fā)中比較常見(jiàn),主要就是將一些與核心業(yè)務(wù)無(wú)關(guān)的功能抽離出來(lái),比如異常處理,日志統(tǒng)計(jì)等。 javascript的函數(shù)式語(yǔ)言特性 我們知道JavaScript使一門(mén)面向?qū)ο蟮木幊陶Z(yǔ)言,但這門(mén)語(yǔ)言同時(shí)擁有很多函數(shù)式語(yǔ)言的特性。 JavaScript的設(shè)計(jì)者在設(shè)計(jì)最初就參考了LISP方言之一的Scheme,引入...
摘要:那么的學(xué)習(xí)就相對(duì)來(lái)說(shuō)很自由了,可以跟著網(wǎng)址過(guò)一遍標(biāo)簽,網(wǎng)上也有很多其它網(wǎng)站做這個(gè)的,像菜鳥(niǎo)教程慕課網(wǎng)視頻之類(lèi)的都可以用等熟練了就可以去國(guó)外看看一些前端的新技術(shù),像國(guó)際,最大的程序員問(wèn)答網(wǎng)站。 前言 前端之路何其漫漫~ ????說(shuō)明:本篇文章原是寫(xiě)給學(xué)弟學(xué)妹的,但想來(lái)花的功夫確實(shí)不少,就把此篇文章當(dāng)做自己的一個(gè)階段性總結(jié)文章了,會(huì)保持長(zhǎng)期更新。 HTML ????總的來(lái)說(shuō)HTML并不難,...
摘要:那么的學(xué)習(xí)就相對(duì)來(lái)說(shuō)很自由了,可以跟著網(wǎng)址過(guò)一遍標(biāo)簽,網(wǎng)上也有很多其它網(wǎng)站做這個(gè)的,像菜鳥(niǎo)教程慕課網(wǎng)視頻之類(lèi)的都可以用等熟練了就可以去國(guó)外看看一些前端的新技術(shù),像國(guó)際,最大的程序員問(wèn)答網(wǎng)站。 前言 前端之路何其漫漫~ ????說(shuō)明:本篇文章原是寫(xiě)給學(xué)弟學(xué)妹的,但想來(lái)花的功夫確實(shí)不少,就把此篇文章當(dāng)做自己的一個(gè)階段性總結(jié)文章了,會(huì)保持長(zhǎng)期更新。 HTML ????總的來(lái)說(shuō)HTML并不難,...
摘要:那么的學(xué)習(xí)就相對(duì)來(lái)說(shuō)很自由了,可以跟著網(wǎng)址過(guò)一遍標(biāo)簽,網(wǎng)上也有很多其它網(wǎng)站做這個(gè)的,像菜鳥(niǎo)教程慕課網(wǎng)視頻之類(lèi)的都可以用等熟練了就可以去國(guó)外看看一些前端的新技術(shù),像國(guó)際,最大的程序員問(wèn)答網(wǎng)站。 前言 前端之路何其漫漫~ ????說(shuō)明:本篇文章原是寫(xiě)給學(xué)弟學(xué)妹的,但想來(lái)花的功夫確實(shí)不少,就把此篇文章當(dāng)做自己的一個(gè)階段性總結(jié)文章了,會(huì)保持長(zhǎng)期更新。 HTML ????總的來(lái)說(shuō)HTML并不難,...
摘要:那么的學(xué)習(xí)就相對(duì)來(lái)說(shuō)很自由了,可以跟著網(wǎng)址過(guò)一遍標(biāo)簽,網(wǎng)上也有很多其它網(wǎng)站做這個(gè)的,像菜鳥(niǎo)教程慕課網(wǎng)視頻之類(lèi)的都可以用等熟練了就可以去國(guó)外看看一些前端的新技術(shù),像國(guó)際,最大的程序員問(wèn)答網(wǎng)站。 前言 前端之路何其漫漫~ ????說(shuō)明:本篇文章原是寫(xiě)給學(xué)弟學(xué)妹的,但想來(lái)花的功夫確實(shí)不少,就把此篇文章當(dāng)做自己的一個(gè)階段性總結(jié)文章了,會(huì)保持長(zhǎng)期更新。 HTML ????總的來(lái)說(shuō)HTML并不難,...
閱讀 3654·2021-08-02 13:41
閱讀 2602·2019-08-30 15:56
閱讀 1568·2019-08-30 11:17
閱讀 1245·2019-08-29 15:18
閱讀 654·2019-08-29 11:10
閱讀 2731·2019-08-26 13:52
閱讀 584·2019-08-26 13:22
閱讀 3027·2019-08-23 15:41