Apa perbedaan antara String (value) vs value.toString ()

105

Javascript memiliki banyak "trik" di sekitar jenis dan jenis konversi jadi saya bertanya-tanya apakah 2 metode ini sama atau jika ada beberapa kasus sudut yang membuatnya berbeda?

AlfaTeK
sumber

Jawaban:

123

Keduanya tidak sepenuhnya sama, dan sebenarnya, konstruktor String yang dipanggil sebagai fungsi (contoh pertama Anda), pada akhirnya akan memanggil toStringmetode objek yang diteruskan, misalnya:

var o = { toString: function () { return "foo"; } };
String(o); // "foo"

Di sisi lain, jika pengenal merujuk ke nullatau undefined, Anda tidak dapat menggunakan toStringmetode ini, ini akan memberi Anda TypeErrorpengecualian :

var value = null;
String(null);     // "null"
value.toString(); // TypeError

The Stringkonstruktor disebut sebagai fungsi akan kira-kira setara dengan:

value + '';

Aturan konversi tipe dari Object- to- Primitive dijelaskan secara rinci pada spesifikasi, [[DefaultValue]]operasi internal.

Secara singkat diringkas, saat mengonversi dari Object- to- String , langkah-langkah berikut diambil:

  1. Jika tersedia, jalankan toStringmetode.
    • Jika resultadalah primitif , kembali result, jika tidak lanjutkan ke Langkah 2.
  2. Jika tersedia, jalankan valueOfmetode.
    • Jika resultadalah primitif , kembali result, jika tidak lanjutkan ke Langkah 3.
  3. Lempar TypeError.

Dengan aturan di atas, kita dapat membuat contoh semantik yang terlibat:

var o = {
  toString: function () { return "foo"; },
  valueOf:  function () { return "bar"; }
};

String(o); // "foo"

// Make the toString method unavailable:
o.toString = null;

String(o); // "bar"

// Also make the valueOf method unavailable:
o.valueOf = null;

try { 
  String(o); 
} catch (e) {
  alert(e); // TypeError
}

Jika Anda ingin mengetahui lebih banyak tentang mekanisme ini, saya akan merekomendasikan untuk melihat ToPrimitivedan ToStringoperasi internal.

Saya juga merekomendasikan membaca artikel ini:

CMS
sumber
1
Ada "cara" ketiga, jika Anda memanggil ini: new String(value)pada nilai apa pun, itu akan selalu mengembalikan objek string.
Herbertusz
@Herbertus new String({toString: null})melempar TypeError.
Константин Ван
Dengan penambahan Symbols String()dan + ''sekarang memiliki perbedaan yang cukup signifikan. String(Symbol())akan berjalan, tetapi Symbol() + ''akan memunculkan kesalahan (dan Symbol () akan melewatkan pelindung palsu, tidak seperti null dan undefined, jadi x && (x + '')sekarang bisa melempar).
yeerk
24

value.toString()akan menyebabkan kesalahan jika valuenol. String(value)jangan.

Sebagai contoh:

var value = null;
alert(value.toString());

akan gagal karena value == null .

var value = null;
alert(String(value));

harus menampilkan pesan bertuliskan "null" (atau serupa), tetapi tidak akan macet.

Jonathan
sumber
3
Saya belum pernah melihat pengecualian pointer nol di javascript ... di mana Anda melihat itu?
Dagg Nabbit
bagus. itu akan menjadi lebih baik dengan sebuah contoh
mykhal
@no, @casablanca Fixed. Saya sudah terbiasa dengan Java. @mykhal Bagaimana kelihatannya?
Jonathan
Ini mengembalikan string "null" :)
moefinley
1

String(value)harus memiliki hasil yang sama seperti value.toString()dalam setiap kasus, kecuali untuk nilai tanpa properti seperti nullatau undefined. ''+valueakan menghasilkan hasil yang sama.

Dagg Nabbit
sumber
1

String () [ panggilan konstruktor ] pada dasarnya memanggil .toString ()

.toString () dan String () dapat dipanggil pada nilai primitif (angka, boolean, string) dan pada dasarnya tidak akan melakukan apa pun yang istimewa:

benar => 'benar'

false => 'false'

17 => '17'

'halo' => 'halo'

Tetapi memanggil fungsi-fungsi ini pada objek adalah tempat yang menarik:

jika objek memiliki fungsi .toString () sendiri, itu akan dipanggil kapan pun Anda membutuhkan objek ini untuk diperlakukan sebagai string (secara eksplisit / implisit)

let obj = {
           myName:"some object",
           toString:function(){ return this.myName; } 
          }

//implicitly treating this obj as a string
"hello " + obj; //"hello some object"

//OR (explicitly)
"hello " + String(obj) //calling the existent toString function

//OR
"hello " + obj.toString(); //calling toString directly

Ngomong-ngomong, jika Anda ingin memperlakukan objek ini sebagai angka, objek ini harus memiliki fungsi .valueOf () yang ditentukan di dalamnya.

bagaimana jika kita memiliki keduanya dalam satu objek?

jika kita ingin memperlakukan objek ini sebagai string => gunakan .toString ()

jika kita ingin memperlakukan objek ini sebagai angka => gunakan .valueOf ()

bagaimana jika kita hanya mendefinisikan .valueOf () ?

.valueOf () yang didefinisikan di dalam objek akan dipanggil apakah kita ingin menangani objek sebagai string atau sebagai angka

Louay Alosh
sumber