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