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