person的讀寫操作 倔強(qiáng),倔的正確讀音是什么?
倔強(qiáng),倔的正確讀音是什么?jué第二聲,“倔”,普通話讀音為jué、juè,初見于傳抄古文。在讀jué時(shí),“倔”的基本含義為頑強(qiáng),固執(zhí),如倔強(qiáng)(jiàng );引申含義為“倔”古同“崛”,突出。在讀j
倔強(qiáng),倔的正確讀音是什么?
jué第二聲,
“倔”,普通話讀音為jué、juè,初見于傳抄古文。在讀jué時(shí),“倔”的基本含義為頑強(qiáng),固執(zhí),如倔強(qiáng)(jiàng );引申含義為“倔”古同“崛”,突出。在讀juè時(shí),“倔”的含義為言語(yǔ)粗直,態(tài)度不好,如那老頭真倔。
在日常使用中,“倔”也常做形容詞,表示奇譎,如倔傀、倔佹。
半條命怎么換第三人稱模式?
控制臺(tái)中輸入sv_cheats1然后保存、讀取再次輸入thirdperson就OK但這種模式效果極差我相信你還會(huì)再輸入一次firstperson的
如何理解JavaScript的原型和原型鏈?
JavaScript中的原型和原型鏈都是實(shí)現(xiàn)OOP的手段,OOP在JavaScript中的具體實(shí)現(xiàn)如下:
對(duì)象(Object)就是屬性(Property)的集合,特別的,稱值(Value)為函數(shù)(Function)的屬性為方法(Method)。將相似對(duì)象的共有屬性提取出來聚集在一起就形成了類(Class),這些對(duì)象稱為該類的實(shí)例(Instance)。同樣,將相似類的共有屬性提取出來聚集在一起也形成新的類,這個(gè)類是前面那些類的超類(Super Class),前面那些類是這個(gè)類的子類(Sub Class)。多個(gè)超類還可以作為子類聚集出一個(gè)新的超類,這個(gè)過程會(huì)一持續(xù)下去,直到出現(xiàn) 名為 Object 的類,它的超類為空(Null)。
類除了是共有屬性的聚集外,還擔(dān)負(fù)對(duì)象工廠(Object Factory)的職責(zé)。一個(gè)類的實(shí)例對(duì)象由類的構(gòu)造函數(shù)(Constructor)負(fù)責(zé)創(chuàng)建。構(gòu)造函數(shù)負(fù)責(zé)兩件事:
創(chuàng)建對(duì)象;
初始化該對(duì)象;
因?yàn)榍罢叩膶?shí)現(xiàn) 已經(jīng)由 方法提供,所以構(gòu)造函數(shù)真正需要完成的就是初始化對(duì)象,這里又分為兩件事情:
讓對(duì)象具有類所聚集的共有屬性;
根據(jù)參數(shù),對(duì)某些對(duì)象的屬性進(jìn)行特化;
對(duì)于第二件事情,沒什么說的,就是將特化的屬性添加到 待初始化的對(duì)象中去。對(duì)于第一件事,也可以仿照后者的實(shí)現(xiàn)方法,但是這不是一個(gè)明智的選擇,因?yàn)檫@些共有屬性的值在大多數(shù)情況下是不會(huì)發(fā)生改變的。JavaScript選擇的方法是:
以這些共有屬性為屬性并賦予默認(rèn)屬性值,創(chuàng)建一個(gè)原型(Prototype)對(duì)象;
初始化時(shí),將原型對(duì)象賦予 待初始化對(duì)象的特殊屬性: __proto__ ;
也就是說,一個(gè)類對(duì)應(yīng)一個(gè)原型對(duì)象,在初始化時(shí),用 __proto___ 將實(shí)例對(duì)象 和 原型對(duì)象連接起來。
特殊屬性 __proto__ 不僅負(fù)責(zé)連接實(shí)例和原型,還負(fù)責(zé)連接子類和超類的原型對(duì)象,以實(shí)現(xiàn)類之間的繼承關(guān)系。這樣以來,一個(gè)對(duì)象的類原型,超類原型,超類的超類原型, ... 就由__proto__連接成一個(gè)“鏈”,稱為該對(duì)象的原型鏈。允許,一個(gè)對(duì)象的 __proto__ 屬性為 null,這表明該對(duì)象沒有原型鏈,Object 類的原型 就是這樣的。
為了讓原型初始化實(shí)例的方法真正得以實(shí)現(xiàn),必須在對(duì)象的屬性訪問上進(jìn)行配合:
讀取屬性值:先在對(duì)象中查找該屬性,如果存在則返回其值,否則,在原型對(duì)象中查找,如果存在則返回其值,否則,在原型對(duì)象的原型對(duì)象中查找,...,直到原型鏈為 null,表示該屬性未定義,返回 undefined;
給屬性賦值:在對(duì)象中查找該屬性,如果存在則對(duì)其賦值,如果不存在則在對(duì)象中創(chuàng)建該屬性然后對(duì)其賦值;
刪除屬性:如果該屬性在對(duì)象中存在則刪除它,否則什么都不做。
這套訪問機(jī)制保證了:對(duì)象屬性可以覆蓋(去覆蓋)原型屬性,但是不會(huì)改變?cè)蛯傩?,這就是OOP的多態(tài)性。
構(gòu)造函數(shù)在創(chuàng)建對(duì)象時(shí)需要用到原型對(duì)象,它是通過 prototype 屬性知道其對(duì)應(yīng)類的原型對(duì)象的。另外,為讓實(shí)例對(duì)象知道是誰(shuí)創(chuàng)建了它,它的constructor 屬性會(huì) “抓著” 構(gòu)造函數(shù)。類的原型對(duì)象也被認(rèn)為是該類的構(gòu)造函數(shù)構(gòu)創(chuàng)建的。
接下來我們看一下實(shí)現(xiàn)OOP的具體代碼:
首先,不考慮繼承關(guān)系,聲明一個(gè)類的范例代碼如下:
注:特殊屬性 __proto__ 是 undocumented 應(yīng)該避免直接使用,正式的做法是調(diào)用 方法,它的參數(shù)就是 所要?jiǎng)?chuàng)建對(duì)象的原型對(duì)象。注:遵照 OOP語(yǔ)言的傳統(tǒng),構(gòu)造函數(shù)的名字就是類的名字。
當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),如果 this 上下文(Context) 綁定的是一個(gè)普通對(duì)象 (而非 null 或 全局對(duì)象 window),則這個(gè)函數(shù)就是作為該對(duì)象的方法被調(diào)用。
當(dāng)我們用new表達(dá)式創(chuàng)建對(duì)象時(shí),構(gòu)造函數(shù)就是以方法的被new調(diào)用:
上面范例代碼中構(gòu)造函數(shù)開始 和 結(jié)束部分 所作的事情,new 表達(dá)式,就替我們干了:
new 會(huì)創(chuàng)建一個(gè) 空白對(duì)象,讓其,原型鏈綁定 構(gòu)造函數(shù)的prototype 屬性, 讓其,constructor 屬性 綁定 構(gòu)造函數(shù);然后 以該對(duì)象 為 this 上下文 調(diào)用 構(gòu)造函數(shù),如果構(gòu)造函數(shù)沒有返回值,則以 空白對(duì)象 作為 創(chuàng)建的對(duì)象。寫成代碼就是:
被 new 調(diào)用的構(gòu)造函數(shù),已經(jīng)轉(zhuǎn)變?yōu)闃?gòu)造方法,但為了讓其還保留構(gòu)造函數(shù)的能力,一般這樣實(shí)現(xiàn):
接下來,考慮類的繼承。
一個(gè)實(shí)例對(duì)象的初始化過程是:先被超類的構(gòu)造函數(shù)初始化,之后才被子類的構(gòu)造函數(shù)初始化,這樣才能達(dá)到子類覆蓋超類的要求?;诖耍独a如下:
寫到這里,我們發(fā)現(xiàn)又是一堆不得不寫的規(guī)范代碼。于是早期很多前端框架,都紛紛的提供了以上代碼的封裝方案,旦各自為政,沒有統(tǒng)一的解決方法,直到 ES6 直接提供了 class 語(yǔ)法,整個(gè)事情才算告一段落:
注:JavaScript中的屬性分為 存儲(chǔ)屬性 和 訪問屬性(分別對(duì)應(yīng)傳統(tǒng)OOP語(yǔ)言 中的 字段(Field) 和 屬性), class 中只能聲明 原型中 方法 和 訪問屬性,而在 原型中 聲明存儲(chǔ)屬性 還得是老辦法。
class 表達(dá)式 只是語(yǔ)法層面的封裝,最終依然是基于原型和原型鏈這套實(shí)現(xiàn)。
雖然我們現(xiàn)在已經(jīng)不需要按照那套復(fù)雜的規(guī)范聲明類了,但是了解原型和原型鏈對(duì)應(yīng)深入理解 JavaScript的OOP機(jī)制依然十分重要。
最后,給出 JavaScript 內(nèi)建對(duì)象 之間的 原型鏈關(guān)系圖(粗箭頭是 __proto__ 屬性,細(xì)箭頭是 prototype 屬性,虛箭頭是 constructor 屬性):
( Value: Number, String, Boolean; Symbol,Container: Array, Set, Map)