2012-04-28 39 views
19

nullundefined không có phương thức toString hoặc valueOf. Afaik sử dụng String gọi phương thức tham số toString của nó (ví dụ: String({}) =>[object Object]).Tại sao String (null) hoạt động?

Tại sao String(null) hoặc String(undefined hoạt động sau đó? Nó không hoàn toàn làm Object.prototype.toString.call(null). bởi vì đánh giá là [object Null].

[chỉnh sửa]: từ thông số kỹ thuật ECMA-262/ấn bản thứ 5 (trang 48). Điều này không thêm để làm rõ, tôi muốn nói:

/* 
Table 13 — ToString Conversions 
------------------------------------------------------------------------- 
Argument Type | Result 
------------------------------------------------------------------------- 
Undefined  | "undefined" 
Null   | "null" 
Boolean  | If the argument is true, then the result is "true". 
...   | ... 
*/ 

Trả lời

22

Sau khi xem lại câu trả lời trước của tôi, có vẻ như việc sửa chữa hoàn toàn câu trả lời trước của tôi là cần thiết. Tôi đã được cách trên phức tạp nó như câu trả lời ngắn gọn là đây là những trường hợp đặc biệt tiêu chuẩn quy định.

Các specification cho String() (String sử dụng như một chức năng):

15.5.1.1 String ([value])

Trả về một giá trị String (không phải là một đối tượng String) tính bằng ToString (giá trị). Nếu giá trị không được cung cấp, thì chuỗi rỗng " " được trả về.

Chức năng ToString (tồn tại trong nội bộ, không phải trong Userland) được định nghĩa như sau (9.8):

"The ToString hoạt động trừu tượng chuyển đổi đối số của nó đến một giá trị kiểu String theo Bảng 13"

Argument Type | Result 
Null | "null" 
Undefined | "undefined" 

Điều này có nghĩa rằng String(null)String(undefined) đi vào bảng đặc biệt này của các loại và chỉ trả lại giá trị chuỗi giá trị "null""undefined".

Một người sử dụng đất giả thực hiện trông giống như sau: (. Lưu ý rằng ví dụ này bỏ qua trường hợp nhà xây dựng (new MyString()) và nó sử dụng các khái niệm sử dụng đất chứ không phải là động cơ-đất)

function MyString(val) { 
    if (arguments.length === 0) { 
     return ""; 
    } else if (typeof val === "undefined") { 
     return "undefined"; 
    } else if (val === null) { 
     return "null"; 
    } else if (typeof val === "boolean") { 
     return val ? "true" : "false"; 
    } else if (typeof val === "number") { 
     // super complex rules 
    } else if (typeof val === "string") { 
     return val; 
    } else { 
     // return MyString(ToPrimitive(val, prefer string)) 
    } 
} 


tôi bị một chút mang đi và tìm thấy một thực hiện ví dụ (V8 được cụ thể):

string.js

// Set the String function and constructor. 
%SetCode($String, function(x) { 
    var value = %_ArgumentsLength() == 0 ? '' : TO_STRING_INLINE(x); 
    if (%_IsConstructCall()) { 
    %_SetValueOf(this, value); 
    } else { 
    return value; 
    } 
}); 

macros.py

macro TO_STRING_INLINE(arg) = (IS_STRING(%IS_VAR(arg)) ? arg : NonStringToString(arg)); 

runtime.js

function NonStringToString(x) { 
    if (IS_NUMBER(x)) return %_NumberToString(x); 
    if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; 
    if (IS_UNDEFINED(x)) return 'undefined'; 
    return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x)); 
} 

Các NonStringToString (trong đó chủ yếu là những gì là quan tâm), được may mắn được định nghĩa trong psuedo-JS-đất. Như bạn có thể thấy, có một trường hợp đặc biệt cho null/true/false/undefined.

+0

Cảm ơn câu trả lời của bạn Corbin, rõ ràng. – KooiInc

+0

@Kooilnc Không sao cả. – Corbin

+0

String()! == Chuỗi (không xác định) là vì trong JavaScript hai đối tượng chỉ bằng nhau nếu chúng là cùng một đối tượng trong bộ nhớ. Khi gọi String(), bạn đang tạo một đối tượng bao quanh chuỗi nguyên thủy để về cơ bản so sánh là hai đối tượng khác nhau gói cùng một chuỗi nguyên thủy. – Buzzy

2

Có thể chỉ là một số kiểm tra bổ sung và xử lý cho các trường hợp đặc biệt như nullundefined.

MDN says:

Có thể sử dụng String như một "an toàn hơn" toString thay thế, như mặc dù nó vẫn thường gọi toString cơ bản, nó cũng làm việc cho null và undefined.

0

String(null) tạo đối tượng chuỗi và chuyển cho nó giá trị mặc định là rỗng.

1

Bạn có thể quan tâm nhìn thấy những Annotated ES5 (mà là nhiều hơn nữa có thể đọc được hơn ECMAScript 5 PDF) trong đó nêu rằng: new String([ value ])http://es5.github.com/#x15.5.2.1 cuộc gọi [ToString]http://es5.github.com/#x9.8 (có một bảng trong các trường hợp chuyển đổi đặc biệt) để chuyển đổi các giá trị truyền cho nó vào một chuỗi.

+1

Đó là bảng chính xác giống như tôi đã liên kết, ngoại trừ màu xanh lá cây có đốm màu. (Và một liên kết trực tiếp) – Corbin

Các vấn đề liên quan