第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么字符串文字在 JavaScript 中被視為原始類型?

為什么字符串文字在 JavaScript 中被視為原始類型?

幕布斯7119047 2022-07-15 10:19:45
官方文檔以及互聯(lián)網(wǎng)上的大量文章都說這'some string'是一個原始值,這意味著每次我們將它分配給一個變量時它都會創(chuàng)建一個副本。但是,這個問題(及其答案)How to force JavaScript to deep copy a string? substr演示了實際上 V8 甚至在方法上也不會復制字符串。每次將字符串傳遞給函數(shù)時都復制字符串也是很瘋狂的,而且沒有意義。在 C#、Java 或 Python 等語言中,String 數(shù)據(jù)類型絕對是一種引用類型。此外,這個鏈接顯示了層次結(jié)構(gòu),我們畢竟可以看到 HeapObject。 https://thlorenz.com/v8-dox/build/v8-3.25.30/html/d7/da4/classv8_1_1internal_1_1_sliced_string.html 最后,經(jīng)過檢查let copy = someStringInitializedAbove在Devtools中,很明顯尚未創(chuàng)建該字符串的新副本!所以我很確定在分配時不會復制字符串。但是我仍然不明白為什么這么多像JS Primitives vs Reference這樣的文章說它們是。
查看完整描述

1 回答

?
慕容森

TA貢獻1853條經(jīng)驗 獲得超18個贊

從根本上說,因為規(guī)范是這樣說的:


字符串值


原始值是零個或多個 16 位無符號整數(shù)值的有限有序序列


該規(guī)范還定義了 String 對象,與原始字符串不同。(類似地,還有原始number、boolean和symbol類型,以及 Number 和 Boolean 和 Symbol 對象。)


原語字符串遵循其他原語的所有規(guī)則。在語言級別上,它們的處理方式與原始數(shù)字和布爾值完全相同。出于所有意圖和目的,它們都是原始值。但是正如您所說,如果a = b從字面上制作字符串的副本b并將該副本放入a. 實現(xiàn)不必這樣做,因為原始字符串值是不可變的(就像原始數(shù)值一樣)。您不能更改字符串中的任何字符,只能創(chuàng)建一個新字符串。如果字符串是可變的,則實現(xiàn)時必須復制一份a = b(但如果它們是可變的,則規(guī)范會以不同的方式編寫)。


請注意,原始字符串和 String 對象確實是不同的東西:


const s = "hey";

const o = new String("hey");


// Here, the string `s` refers to is temporarily

// converted to a string object so we can perform an

// object operation on it (setting a property).

s.foo = "bar";

// But that temporary object is never stored anywhere,

// `s` still just contains the primitive, so getting

// the property won't find it:

console.log(s.foo); // undefined


// `o` is a String object, which means it can have properties

o.foo = "bar";

console.log(o.foo); // "bar"

那么為什么要有原始字符串呢?你得問 Brendan Eich(他在 Twitter 上的反應很合理),但我懷疑這是因為等價運算符(==、===、!=和!==)的定義不必是可能被用于其自身目的的對象類型,或用于字符串的特殊情況。


那么為什么要有字符串對象呢?擁有 String 對象(以及 Number 對象、Boolean 對象和 Symbol 對象)以及說明何時創(chuàng)建原語的臨時對象版本的規(guī)則使得在原語上定義方法成為可能。當你這樣做時:


console.log("example".toUpperCase());

在規(guī)范術(shù)語中,創(chuàng)建一個 String 對象(通過GetValue 操作),然后toUpperCase在該對象上查找屬性并(在上面)調(diào)用。因此,原始字符串從和獲取它們的toUpperCase(和其他標準方法)。但是除非在某些邊緣情況下,否則代碼無法訪問創(chuàng)建的臨時對象,并且 JavaScript 引擎可以避免在這些邊緣情況之外創(chuàng)建對象。這樣做的好處是可以在原始字符串中添加和使用新方法。String.prototypeObject.prototypeString.prototype


1“什么邊緣情況?” 我聽到你問。我能想到的最常見的一種方法是當您String.prototype在松散模式代碼中添加自己的方法(或類似方法)時:


Object.defineProperty(String.prototype, "example", {

    value() {

        console.log(`typeof this: ${typeof this}`);

        console.log(`this instance of String: ${this instanceof String}`);

    },

    writable: true,

    configurable: true

});


"foo".example();

// typeof this: object

// this instance of String: true

在那里,JavaScript 引擎被迫創(chuàng)建 String 對象,因為this在松散模式下不能是原語。


嚴格模式可以避免創(chuàng)建對象,因為在嚴格模式下this不需要是對象類型,它可以是原始類型(在本例中為原始字符串):


"use strict";

Object.defineProperty(String.prototype, "example", {

    value() {

        console.log(`typeof this: ${typeof this}`);

        console.log(`this instance of String: ${this instanceof String}`);

    },

    writable: true,

    configurable: true

});


"foo".example();

// typeof this: string

// this instanceof String: false


查看完整回答
反對 回復 2022-07-15
  • 1 回答
  • 0 關(guān)注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號