Khái niệm cơ bản
Bạn có thể không biết điều đó, nhưng trong JavaScript, bất cứ khi nào chúng ta tương tác với các nguyên hàm chuỗi, số hoặc boolean, chúng ta sẽ bước vào một thế giới ẩn của bóng và đối tượng ẩn.
chuỗi, số, boolean, null, không xác định và ký hiệu.
Trong JavaScript có 7 loại nguyên thủy: undefined
, null
, boolean
, string
, number
, bigint
và symbol
. Mọi thứ khác là một đối tượng. Các kiểu nguyên thủy boolean
, string
và number
có thể được bao bọc bởi các đối tác của chúng. Những đối tượng là trường hợp của Boolean
, String
và Number
nhà xây dựng tương ứng.
typeof true; //"boolean"
typeof new Boolean(true); //"object"
typeof "this is a string"; //"string"
typeof new String("this is a string"); //"object"
typeof 123; //"number"
typeof new Number(123); //"object"
Nếu nguyên thủy không có thuộc tính, tại sao "this is a string".length
trả về một giá trị?
Bởi vì JavaScript sẽ dễ dàng ép buộc giữa các nguyên thủy và các đối tượng. Trong trường hợp này, giá trị chuỗi được ép buộc vào một đối tượng chuỗi để truy cập vào độ dài thuộc tính. Đối tượng chuỗi chỉ được sử dụng trong một phần giây sau đó nó được hiến tế cho Thần thu gom rác - nhưng theo tinh thần của chương trình khám phá trên TV, chúng tôi sẽ bẫy sinh vật khó nắm bắt và bảo tồn nó để phân tích thêm
Để chứng minh điều này, hãy xem xét thêm ví dụ sau trong đó chúng tôi đang thêm một thuộc tính mới vào nguyên mẫu hàm tạo chuỗi.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
Điều này có nghĩa là người nguyên thủy có quyền truy cập vào tất cả các thuộc tính (bao gồm các phương thức) được xác định bởi các hàm tạo đối tượng tương ứng của chúng.
Vì vậy, chúng tôi đã thấy rằng các kiểu nguyên thủy sẽ cưỡng chế một cách thích hợp đối tác Đối tượng tương ứng của chúng khi được yêu cầu.
Phân tích toString()
phương pháp
Hãy xem xét các mã sau đây
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
myObj.toString(); // "[object Object]"
myFunc.toString(); // "function(){}"
myString.toString(); // "This is a sample String"
myNumber.toString(); // "4"
myArray.toString(); // "2,3,5"
Như đã thảo luận ở trên, những gì thực sự xảy ra là khi chúng ta gọi toString()
phương thức theo kiểu nguyên thủy, nó phải được ép buộc vào đối tác của nó trước khi nó có thể gọi phương thức.
tức myNumber.toString()
là tương đương vớiNumber.prototype.toString.call(myNumber)
và tương tự cho các loại nguyên thủy khác.
Nhưng điều gì sẽ xảy ra nếu thay vì kiểu nguyên thủy được truyền vào toString()
phương thức của đối tác hàm xây dựng đối tượng tương ứng của nó, chúng ta buộc loại nguyên thủy được truyền dưới dạng tham số vào toString()
phương thức của hàm xây dựng hàm Object ( Object.prototype.toString.call(x)
)?
Nhìn kỹ hơn vào Object.prototype.toString ()
Theo tài liệu , khi phương thức toString được gọi, các bước sau được thực hiện:
- Nếu
this
giá trị là undefined
, trả về"[object Undefined]"
.
- Nếu
this
giá trị là null
, trả về"[object Null]"
.
- Nếu giá trị này không có giá trị nào ở trên, hãy
O
là kết quả của việc gọi toObject
vượt quathis
giá trị làm đối số.
- Đặt lớp là giá trị của
[[Class]]
tài sản nội bộ của O
.
- Trả lại giá trị String mà là kết quả của concatenating ba Strings
"[object "
, class
và "]"
.
Hiểu điều này từ ví dụ sau
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
var myUndefined = undefined;
var myNull = null;
Object.prototype.toString.call(myObj); // "[object Object]"
Object.prototype.toString.call(myFunc); // "[object Function]"
Object.prototype.toString.call(myString); // "[object String]"
Object.prototype.toString.call(myNumber); // "[object Number]"
Object.prototype.toString.call(myArray); // "[object Array]"
Object.prototype.toString.call(myUndefined); // "[object Undefined]"
Object.prototype.toString.call(myNull); // "[object Null]"
Tài liệu tham khảo:
https://es5.github.io/x15.2.html#x15.2.4.2
https://es5.github.io/x9.html#x9.9
https://javascriptweblog.wordpress.com/ 2010/09/27 / the-secret-life-of-javascript-primitive /