2010-09-21 36 views
5

Tôi tự hỏi tại sao có vẻ như việc thêm một phương thức vào nguyên mẫu của một chuỗi ký tự có vẻ hoạt động, nhưng thêm một thuộc tính thì không? Tôi đã chơi với các ý tưởng liên quan đến this question và có mã sau:Đối tượng chuỗi so với chữ - sửa đổi nguyên mẫu?

String.prototype._str_index1 = 0; 
String.prototype._str_reset = function() { 
    this._str_index1 = 0; 
}; 
String.prototype._str_substr = function(len) { 
    var ret = this.substr(this._str_index1, len); 
    this._str_index1 = this._str_index1 + len; 
    return ret; 
}; 

var testString = new String('Loremipsumdolorsitamet,consectetur'); 
log(testString._str_substr(5)); 
log(testString._str_substr(4)); 
​ 

Điều này làm việc tốt. Tuy nhiên, nếu tôi thay đổi dòng cuối cùng thứ ba nào:

var testString = 'Loremipsumdolorsitamet,consectetur'; 

... có vẻ như rằng mặc dù các phương pháp _str_substr tồn tại và có thể được gọi vào chuỗi chữ, giá trị của tài sản _str_index1 luôn là 0.

Có chuyện gì vậy?

+0

* Hầu hết * những thứ bạn gọi là 'chuỗi chữ', được gọi là 'chuỗi nguyên thủy': literals là cú pháp để mô tả chuỗi, ví dụ, để gán một chuỗi (hoặc số, boolean, đối tượng, v.v. .) vào một biến; giá trị nguyên thủy là các giá trị không tổng hợp mà các biến và đối tượng có thể chứa (ngoài các đối tượng khác). –

+0

Trừ khi nó không .... 'indexOf' không phải là một hàm khi được gọi chống lại một chuỗi .... –

Trả lời

8

Chuỗi nguyên thủy được chuyển đổi thành một đối tượng tạm thời String mỗi lần bạn cố gắng gọi một phương thức của đối tượng String (công cụ JavaScript chuyển đổi nội dung chuỗi gốc thành đối tượng String khi cần thiết). Sau khi hàm này trả về, đối tượng String là (không phô trương) được chuyển đổi thành một chuỗi nguyên thủy (dưới mui xe) và nguyên thủy mới này được trả về (và phần lớn thời gian được gán cho một biến); mỗi lần một phương thức của đối tượng String được gọi.

Vì vậy, sau mỗi lần gọi của testString._str_substr, _str_index1 được ném đi với đối tượng và một đối tượng mới (với một thiết lập lại _str_index1) được tạo ra khi _str_substr được gọi một lần nữa.

Xem thêm MDC:

Bởi vì JavaScript tự động chuyển đổi giữa nguyên thủy chuỗi và các đối tượng String, bạn có thể gọi bất kỳ phương pháp của đối tượng String trên một chuỗi nguyên thủy. JavaScript tự động chuyển đổi chuỗi gốc thành đối tượng String tạm thời, gọi phương thức, sau đó loại bỏ đối tượng String tạm thời.

+0

Vâng, đó là khá nhiều những gì tôi đã cố gắng để nói :) –

2

Điều này xảy ra vì đối tượng được tạo ra và ngay lập tức bị vứt bỏ khi việc gán được thực hiện, bởi vì nó là một chuỗi chữ.

Vì vậy, với phiên bản đầu tiên, một đối tượng được tạo và lưu giữ, vì vậy testString là một đối tượng, không phải là một chuỗi ký tự. Trong trường hợp thứ hai, một đối tượng được tạo ra và vứt bỏ, vì vậy tất cả các thuộc tính bị lạc ...

Bây giờ hãy thử thay thế dòng đó với điều này:

var testString = 'Loremipsumdolorsitamet,consectetur'._str_substr(); 

Thú vị, phải không? Nó vẫn trả về một chuỗi nguyên thủy, nhưng điều đó có thể được cố định ...

String.prototype._str_substr = function(len) { 
    var ret = this.substr(this._str_index1, len); 
    this._str_index1 = this._str_index1 + len; 
    return new String(ret); 
}; 

Tất nhiên những chỉ là gợi ý thiết kế để giúp giải thích tại sao literals hành động khác biệt so với các đối tượng, không khuyến nghị thực tế ...

+0

Tôi không hiểu. – spender

+0

Không có tôi. @no, tôi không có ý tưởng những gì bạn có ý nghĩa. – sje397

+0

"đối tượng được tạo ra và ngay lập tức bị vứt bỏ khi gán được" âm thanh như một đối tượng được tạo ra và vứt bỏ trên * initial * assignment ('var testString =…'), không phải khi gọi '_str_substr'. –

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