摘要:那么也一并被刪除了。然后我們基本就沒(méi)法寫(xiě)代碼了不存在,因?yàn)闆](méi)有定義過(guò)啊的意義就是把共有屬性預(yù)先定義好,給之后的對(duì)象用。
本文為饑人谷講師方方原創(chuàng)文章。
你的 JS 代碼還沒(méi)運(yùn)行的時(shí)候,JS 環(huán)境里已經(jīng)有一個(gè) window 對(duì)象了
window 對(duì)象有一個(gè) Object 屬性,window.Object 是一個(gè)函數(shù)對(duì)象
window.Object 這個(gè)函數(shù)對(duì)象有一個(gè)重要屬性是 prototype,干什么用的等會(huì)說(shuō)
window.Object.prototype 里面有這么幾個(gè)屬性 toString(函數(shù))、valueOf(函數(shù))
好,目前先知道這些就夠了。
然后我們寫(xiě)一句代碼
var obj = {} obj.toString()
這句代碼做了啥?為什么 obj 有 toString() 屬性?
這句話大概是讓 obj 變量指向一個(gè)空對(duì)象,這個(gè)空對(duì)象有個(gè) proto 屬性指向 window.Object.prototype。
這樣你在調(diào)用 obj.toString() 的時(shí)候,obj 本身沒(méi)有 toString,就去 obj.__proro__ 上面去找 toString。
所以你調(diào)用 obj.toString 的時(shí)候,實(shí)際上調(diào)用的是 window.Object.prototype.toString
那么 window.Object.prototype.toString 是怎么獲取 obj 的內(nèi)容的呢?
那是因?yàn)?obj.toString() 等價(jià)于 obj.toString.call(obj)
同時(shí) obj.toString.call(obj) 等價(jià)于 window.Object.prototype.toString.call(obj)
這句話把 obj 傳給 toString 了。
再看復(fù)雜一點(diǎn)的回到第一幅圖
我們寫(xiě)一句代碼
var arr = [] arr.push(1) // [1]
請(qǐng)問(wèn)這兩句話做了什么?
看紅色部分,var arr = [] 大概會(huì)讓 arr 指向一個(gè)空對(duì)象,然后 arr.__proto__ 指向 window.Array.prototype。(其實(shí) arr 有一個(gè) length:0,不過(guò)這里就忽略吧)
這樣你在調(diào)用 arr.push 的時(shí)候,arr 自身沒(méi)有 push 屬性,就去 arr.__proto__ 上找 push
因此 arr.push 實(shí)際上是 window.Array.prototype.push
arr.push(1) 等價(jià)與 arr.push.call(arr,1)
arr.push.call(arr,1) 等價(jià)于 window.Array.prototype.push.call(arr, 1)
再再?gòu)?fù)雜一點(diǎn)arr.valueOf() 做了什么?
arr 自身沒(méi)有 valueOf,于是去 arr.__proto__ 上找
arr.__proto__ 只有 pop、push 也沒(méi)有 valueOf,于是去 arr.__proto__.__proto__ 上找
arr.__proto__.__proto__ 就是 window.Object.prototype
所以 arr.valueOf 其實(shí)就是 window.Object.prototype.valueOf
arr.valueOf() 等價(jià)于 arr.valueOf.call(arr)
arr.valueOf.call(arr) 等價(jià)于 window.Object.prototype.valueOf.call(arr)
看,JavaScript 其實(shí)很優(yōu)美很簡(jiǎn)單。
只是你想復(fù)雜了而已:
prototype 指向一塊內(nèi)存,這個(gè)內(nèi)存里面有共用屬性
proto 指向同一塊內(nèi)存
prototype 和 proto 的不同點(diǎn)在于
prototype 是構(gòu)造函數(shù)的屬性,而 proto 是對(duì)象的屬性
難點(diǎn)在于……構(gòu)造函數(shù)也是對(duì)象!
如果沒(méi)有 prototype,那么共用屬性就沒(méi)有立足之地
如果沒(méi)有 __proto__,那么一個(gè)對(duì)象就不知道自己的共用屬性有哪些。
反證法假設(shè)我們把 proto 去掉,那么
var obj = {} obj.toString() // 報(bào)錯(cuò),沒(méi)有 toString 方法
所以你只能這樣聲明一個(gè)對(duì)象咯:
var obj = { toString: window.Object.prototype.toString, valueOf: window.Object.ptototype.valueOf } obj.toString() // "[object Object]"
知道 proto 幫你省多少代碼了嗎?
假設(shè)我們刪掉 prototype,包括 window.Object.prototype 和 window.Array.prototype。
那么 window.Object.prototype.toString 也一并被刪除了。
然后我們基本就沒(méi)法寫(xiě)代碼了……
var obj = {} obj.toString() // toString 不存在,因?yàn)?toString 沒(méi)有定義過(guò)啊
prototype 的意義就是把共有屬性預(yù)先定義好,給之后的對(duì)象用。
自己想想吧~
新人搞不懂原型大抵是因?yàn)?/p>
不懂內(nèi)存、引用
不懂鏈表、樹(shù)等數(shù)據(jù)結(jié)構(gòu)
不知道函數(shù)是一種對(duì)象
被 Java 的 class 關(guān)鍵字毒害了
還有一種可能是因?yàn)闆](méi)遇到我方應(yīng)杭:
「每日一題」什么是 JS 原型鏈?
JS 的 new 到底是干什么的?
this 的值到底是什么?一次說(shuō)清楚
以上是「方三篇」新人一定要看哦。
想看視頻版本可以購(gòu)買(mǎi)我的網(wǎng)課(收費(fèi)):
JS 深入淺出 - 寫(xiě)代碼啦!
這幅圖我還可以繼續(xù)講,把 JS 所有基礎(chǔ)知識(shí)都能串起來(lái)。
比如很多人不懂什么是偽數(shù)組,很簡(jiǎn)單:
如果一個(gè)數(shù)組的 proto 直接或間接指向 Array.prototye(用到了數(shù)組的共用屬性),那么就是真數(shù)組
如果一個(gè)數(shù)組的 proto 沒(méi)有直接或間接指向 Array.prototye,那么就是偽數(shù)組
var realArr = {0: "a", 1:"b", length: 2} realArr.__proto__ = Array.prototye // 這就是真數(shù)組 // 等價(jià)于 realArr = ["a", "b"] realArr.push !== undefined // true var fakeArr = {0: "a", 1:"b", length: 2} // 這就是偽數(shù)組 realArr.push === undefined // true
完。
加微信號(hào): astak10或者長(zhǎng)按識(shí)別下方二維碼進(jìn)入前端技術(shù)交流群 ,暗號(hào):寫(xiě)代碼啦
每日一題,每周資源推薦,精彩博客推薦,工作、筆試、面試經(jīng)驗(yàn)交流解答,免費(fèi)直播課,群友輕分享... ,數(shù)不盡的福利免費(fèi)送
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107396.html
首先明確兩個(gè)概念: 構(gòu)造函數(shù)和 instance 分別是什么 構(gòu)造函數(shù)JS 中并沒(méi)有在語(yǔ)法層面上面區(qū)分構(gòu)造函數(shù)和普通函數(shù), 唯一的區(qū)別是調(diào)用方式使用 new 調(diào)用的函數(shù)就是構(gòu)造函數(shù), 沒(méi)有則是普通函數(shù). 實(shí)例new Constructor() 返回的對(duì)象稱為 Constructor 的一個(gè)實(shí)例 然后提出一個(gè)規(guī)則:在構(gòu)造函數(shù)的原型上面附加的屬性或者方法, 可以被其所有的實(shí)例共用. 可以推導(dǎo)出: ...
摘要:另外常說(shuō)的的構(gòu)造函數(shù),就是指這個(gè)。按照理解,可能會(huì)這樣的疑問(wèn)指向構(gòu)造函數(shù)再次提醒,是一個(gè)對(duì)象的,所以這個(gè)對(duì)象的構(gòu)造函數(shù)是它自己自己創(chuàng)建自己么額。。。 本文由用途意義,進(jìn)行腦測(cè)解析,從需求角度走一遍原型鏈的發(fā)展。 用對(duì)象模擬類的繼承 js中沒(méi)有類(沒(méi)有類,沒(méi)有類,重要的事情說(shuō)3遍)只有對(duì)象,怎么才能做到繼承的效果? var a={x:1} var b={}; b.__proto__=a...
摘要:上面的代碼,運(yùn)行以后,我們可以看到因?yàn)榈脑褪侵赶虻膶?shí)例上的,所以可以訪問(wèn)他的屬性值,那如果我不想讓訪問(wèn)的構(gòu)造函數(shù)里聲明的屬性值,那怎么辦呢只需要將指向的原型而不是實(shí)例就行了。 走在前端的大道上 本篇將自己讀過(guò)的相關(guān) javascript原型和原型鏈 文章中,對(duì)自己有啟發(fā)的章節(jié)片段總結(jié)在這(會(huì)對(duì)原文進(jìn)行刪改),會(huì)不斷豐富提煉總結(jié)更新。 文章——深入理解javascript之原型 一般的...
摘要:原型鏈?zhǔn)紫?,的?duì)象普通對(duì)象和函數(shù)對(duì)象都會(huì)有屬性,指向創(chuàng)建它的構(gòu)造函數(shù)的原型對(duì)象,比如上面的例子這就形成了原型鏈,會(huì)一直查找原型對(duì)象的屬性,直到為。,保證原型鏈能夠正常結(jié)束。 前言 一般談到j(luò)s中的繼承的時(shí)候,一定會(huì)遇到原型,原型鏈的問(wèn)題,原型里面又有prototype,__proto__,constructor屬性,講到這兒,很多同學(xué)是不是都一頭霧水,傻傻分不清楚,因?yàn)楣ぷ髦杏玫降牡胤?..
摘要:全局對(duì)象規(guī)定全局對(duì)象叫做,但是瀏覽器把作為全局對(duì)象瀏覽器先存在的。就是一個(gè)哈希表,里面含有很多屬性。對(duì)象表示一個(gè)包含文檔的窗口,其屬性指向窗口中載入的文檔。使用屬性可以獲取指定文檔所在窗口。在標(biāo)簽瀏覽器比如中,每個(gè)標(biāo)簽具有自己的對(duì)象。 全局對(duì)象 ECMAScript規(guī)定全局對(duì)象叫做global,但是瀏覽器把window作為全局對(duì)象(瀏覽器先存在的)。window就是一個(gè)哈希表,里面含有...
閱讀 1133·2021-09-22 15:37
閱讀 1159·2021-09-13 10:27
閱讀 2518·2021-08-25 09:38
閱讀 2474·2019-08-26 11:42
閱讀 1555·2019-08-26 11:39
閱讀 1591·2019-08-26 10:58
閱讀 2372·2019-08-26 10:56
閱讀 2600·2019-08-23 18:08