摘要:我們開始應(yīng)用上規(guī)范上的步驟,雖然賦值運(yùn)算符具有右結(jié)合性,然而它首先做的是得到表達(dá)式的值,根據(jù)我們對(duì)的解釋它返回一個(gè)指向?qū)ο蟮某蓡T的引用,需要注意的是,這個(gè)時(shí)候并沒有改變引用的指向。
可以在這里看:http://leozdgao.me/renew-js-assignment/
此文的目的是為了解釋如下現(xiàn)象:
var foo = { n: 1 }; var bar = foo; foo.x = foo = { n: 2 }; console.log(foo.x); // undefined賦值運(yùn)算符
根據(jù)ECMA規(guī)范中的定義賦值運(yùn)算符的產(chǎn)生式(production)以及運(yùn)算過程如下:
The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:
Let lref be the result of evaluating LeftHandSideExpression.
Let rref be the result of evaluating AssignmentExpression.
Let rval be GetValue(rref).
Throw a SyntaxError exception if the following conditions are all true:
Type(lref) is Reference is true
IsStrictReference(lref) is true
Type(GetBase(lref)) is Environment Record
GetReferencedName(lref) is either "eval" or "arguments"
Call PutValue(lref, rval).
Return rval.
其實(shí)第一次看這個(gè)部分我也還是無法理解開始列出的那個(gè)代碼中結(jié)果到底是為什么,看了其他博客其實(shí)也沒有講清楚,在StackOverflow上相關(guān)問題中有解釋到說是因?yàn)槭紫冉馕鲎筮叡磉_(dá)式時(shí)確定了引用的指向,而只看11.13.1的話,只有一句“獲取LeftHandSideExpression的計(jì)算結(jié)果”,所以我覺得要真正理解,只看11.13.1是不行,還需要了解下11.2.1關(guān)于Property Accessors的內(nèi)容,從而知道這個(gè)“計(jì)算結(jié)果是如何得到的”:
The production MemberExpression : MemberExpression [ Expression ] is evaluated as follows:
Let baseReference be the result of evaluating MemberExpression.
Let baseValue be GetValue(baseReference).
Let propertyNameReference be the result of evaluating Expression.
Let propertyNameValue be GetValue(propertyNameReference).
Call CheckObjectCoercible(baseValue).
Let propertyNameString be ToString(propertyNameValue).
If the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false.
Return a value of type Reference whose base value is baseValue and whose referenced name is propertyNameString, and whose strict mode flag is strict.
關(guān)鍵點(diǎn)在于它的返回值,用一個(gè)栗子來解釋就是說:如果有表達(dá)式foo.x,則它的返回值是一個(gè)指向foo對(duì)象x屬性的引用。
那么在知道了這一點(diǎn)后,開始解釋上面的現(xiàn)象:
首先是兩個(gè)變量的聲明和初始化,var foo = { n: 1 }; var bar = foo;,這個(gè)很好理解,就是foo和bar同時(shí)指向了一個(gè)相同的對(duì)象{ n: 1 }。
接下來,對(duì)于表達(dá)式foo.x = foo = { n: 2 };,我們都知道它實(shí)際上等于是foo.x = (foo = { n: 2 })。我們開始應(yīng)用上ECMA規(guī)范上的步驟,雖然賦值運(yùn)算符具有右結(jié)合性,然而它首先做的是得到表達(dá)式foo.x的值,根據(jù)我們對(duì)Property Accessors的解釋它返回一個(gè)指向?qū)ο?b>{ n: 1}的x成員的引用,需要注意的是,這個(gè)時(shí)候foo并沒有改變引用的指向。
繼續(xù),開始計(jì)算右邊的結(jié)果,就是讓foo指向另外的一個(gè)對(duì)象{n: 2},返回值就是其右邊運(yùn)算式(operand)的結(jié)果,即對(duì)象{n: 2}這個(gè)容易理解。
那么現(xiàn)在應(yīng)該清楚了,賦值語(yǔ)句中foo.x的結(jié)果是指向?qū)ο笠怀蓡Tx的引用,而下面的console.log(foo.x)中的foo指向的是對(duì)象二,所以這里foo.x返回undefined就理所當(dāng)然了。
所以試著輸出對(duì)象一,即bar(因?yàn)樗鼜氖贾两K指向的是對(duì)象一):
{ n: 1, x: { n: 2 } }
如果有其他看法,接受各種形式的補(bǔ)充和指正。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85783.html
摘要:當(dāng)你用該日期類創(chuàng)建一個(gè)對(duì)象時(shí),編譯器會(huì)自動(dòng)調(diào)用該構(gòu)造函數(shù)對(duì)新創(chuàng)建的變量進(jìn)行初始化。注意構(gòu)造函數(shù)的主要任務(wù)并不是開空間創(chuàng)建對(duì)象,而是初始化對(duì)象。編譯器對(duì)內(nèi)置類型使用默認(rèn)構(gòu)造函數(shù)時(shí),對(duì)其成員賦的是隨機(jī)值。 ...
摘要:之前寫過一篇文章面試官問能否模擬實(shí)現(xiàn)的和方法就是利用對(duì)象上的函數(shù)指向這個(gè)對(duì)象,來模擬實(shí)現(xiàn)和的。雖然實(shí)際使用時(shí)不會(huì)顯示返回,但面試官會(huì)問到。非嚴(yán)格模式下,和,指向全局對(duì)象 前言 面試官出很多考題,基本都會(huì)變著方式來考察this指向,看候選人對(duì)JS基礎(chǔ)知識(shí)是否扎實(shí)。讀者可以先拉到底部看總結(jié),再谷歌(或各技術(shù)平臺(tái))搜索幾篇類似文章,看筆者寫的文章和別人有什么不同(歡迎在評(píng)論區(qū)評(píng)論不同之處),...
摘要:到目前為止,我們的環(huán)境只包含全局幀。要注意函數(shù)名稱是重復(fù)的,一個(gè)在幀中,另一個(gè)是函數(shù)的一部分。運(yùn)算符字表達(dá)式是全局幀中發(fā)現(xiàn)的名稱,綁定到了內(nèi)建的加法函數(shù)上。嚴(yán)格來說,這并不是問題所在不同局部幀中的的綁定是不相關(guān)的。 1.3 定義新的函數(shù) 來源:1.3 Defining New Functions 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 我們已經(jīng)在 Python 中認(rèn)識(shí)...
摘要:不支持嚴(yán)格模式的瀏覽器與嚴(yán)格模式的瀏覽器行為也不一樣,所以不要在未經(jīng)嚴(yán)格模式特性測(cè)試情況下使用嚴(yán)格模式。在嚴(yán)格模式下,使用上述標(biāo)識(shí)符作為變量名會(huì)導(dǎo)致語(yǔ)法錯(cuò)誤。嚴(yán)格模式下,命名參數(shù)與對(duì)象是完全獨(dú)立的。在嚴(yán)格模式下,函數(shù)的值始終是指定的值。 嚴(yán)格模式 概述 嚴(yán)格模式是什么 嚴(yán)格模式是JavaScript中的一種限制性更強(qiáng)的變種模式。嚴(yán)格模式不是一個(gè)子集:它的語(yǔ)義上與正常代碼有著明顯的差異。...
摘要:序列是中的重要數(shù)據(jù)結(jié)構(gòu),序列包括字符串,列表,元組。序列支持運(yùn)算符嗎運(yùn)算符是否支持算數(shù)運(yùn)算符支持加法與乘法操作,返回新的序列比較運(yùn)算符支持,返回與邏輯運(yùn)算符支持注意必須是同種類型數(shù)據(jù)結(jié)構(gòu)操作才有意義。 序列是Python中的重要數(shù)據(jù)結(jié)構(gòu),序列包括字符串,列表,元組。大部分朋友學(xué)習(xí)Python的時(shí)候都會(huì)找本書或者資料從頭看到尾,這次我們換一個(gè)思路,問答式的方式,可能讓我們精力更集中,下面...
閱讀 1083·2021-11-16 11:45
閱讀 2731·2021-09-27 13:59
閱讀 1327·2021-08-31 09:38
閱讀 3158·2019-08-30 15:52
閱讀 1323·2019-08-29 13:46
閱讀 2095·2019-08-29 11:23
閱讀 1654·2019-08-26 13:47
閱讀 2502·2019-08-26 11:54