Bản đánh máy: sự khác biệt giữa Chuỗi và chuỗi


256

Có ai biết sự khác biệt giữa Chuỗi và chuỗi trong TypeScript không? Tôi có đúng không khi cho rằng họ phải giống nhau?

var a: String = "test";
var b: string = "another test";
a = b;
b = a; // this gives a compiler error!

Phiên bản hiện tại của trình biên dịch cho biết:

Type 'String' is not assignable to type 'string'.
  'string' is a primitive, but 'String' is a wrapper object.
     Prefer using 'string' when possible.

Đó có phải là một lỗi không?


1
Tôi nghĩ rằng "đó là một lỗi" thực sự là một câu hỏi triết học tốt. Có thể "dự định" là như vậy nhưng nó tạo ra sự nhầm lẫn và biên dịch lỗi. Tôi nghĩ đó ít nhất là một vấn đề.
Gherman

Câu trả lời:


252

Dưới đây là một ví dụ cho thấy sự khác biệt, sẽ giúp giải thích.

var s1 = new String("Avoid newing things where possible");
var s2 = "A string, in TypeScript of type 'string'";
var s3: string;

Stringlà loại Chuỗi JavaScript mà bạn có thể sử dụng để tạo chuỗi mới. Không ai làm điều này như trong JavaScript, các chữ được coi là tốt hơn, vì vậy s2trong ví dụ trên tạo ra một chuỗi mới mà không sử dụng newtừ khóa và không sử dụng rõ ràng Stringđối tượng.

string là loại chuỗi TypeScript, bạn có thể sử dụng để nhập biến, tham số và trả về giá trị.

Ghi chú bổ sung ...

Hiện tại (Tháng 2 năm 2013) Cả hai s1s2đều là JavaScript hợp lệ. s3là TypeScript hợp lệ.

Sử dụng String. Bạn có thể không bao giờ cần sử dụng nó, chuỗi ký tự được chấp nhận phổ biến là cách chính xác để khởi tạo một chuỗi. Trong JavaScript, nó cũng được coi là tốt hơn để sử dụng các đối tượng bằng chữ và cả mảng bằng chữ:

var arr = []; // not var arr = new Array();
var obj = {}; // not var obj = new Object();

Nếu bạn thực sự có một xu hướng cho chuỗi, bạn có thể sử dụng nó trong TypeScript theo một trong hai cách ...

var str: String = new String("Hello world"); // Uses the JavaScript String object
var str: string = String("Hello World"); // Uses the TypeScript string type

Thanx để xóa nó ra. Vì vậy, an toàn khi sử dụng chuỗi loại primitve để tránh các sự cố chuyển đổi loại có thể xảy ra khi sử dụng các lib khác hoạt động với các giá trị chuỗi (dựa trên ý tưởng rằng không ai thực sự sử dụng Chuỗi (?)). Việc gán giữa chuỗi và Chuỗi và ngược lại có nên được xử lý như nhau không?
Paul0515

1
Thực sự an toàn khi sử dụng vì các loại TypeScript được loại bỏ để cung cấp cho bạn JavaScript tương thích 100% (trong các hương vị ES3 hoặc ES5 và trong phiên bản ES6 phiên bản 1). Tôi khuyên bạn nên sử dụng stringloại và khởi tạo theo nghĩa đen : var s: string = "My String";.
Fenton

đối với bản ghi, nhờ vào suy luận kiểu, var s: string = "My String"giống hệt với var s = "My String"... cũng vậy, cho dù tôi có đọc phản hồi này bao nhiêu lần đi chăng nữa, tôi vẫn không nắm được mục đích của stringloại trong TypeScript, kể từ cuối ngày , ('My String')['constructor'] === String...
mindplay.dk

2
Thông thường bạn sẽ thêm chú thích nếu bạn không khởi tạo biến bằng một giá trị.
Fenton

2
Tôi đã thêm một câu trả lời để làm rõ rằng "foo" so với Chuỗi mới ("foo") không phải là một sự khác biệt mới được TypeScript giới thiệu - Tôi không nghĩ nên gọi một loại JS và loại TS khác là hữu ích.
Joe Lee-Moyet

60

Hai loại khác nhau về JavaScript cũng như TypeScript - TypeScript chỉ cung cấp cho chúng ta cú pháp để chú thích và kiểm tra các loại khi chúng ta đi cùng.

Stringđề cập đến một thể hiện đối tượng có String.prototypetrong chuỗi nguyên mẫu của nó. Bạn có thể lấy một ví dụ như vậy theo nhiều cách khác nhau, vd new String('foo')Object('foo'). Bạn có thể kiểm tra một thể hiện của Stringloại với instanceoftoán tử, vd myString instanceof String.

stringlà một trong những kiểu nguyên thủy của JavaScript và stringcác giá trị chủ yếu được tạo bằng chữ, ví dụ 'foo'"bar", là loại kết quả của các hàm và toán tử khác nhau. Bạn có thể kiểm tra stringloại bằng cách sử dụng typeof myString === 'string'.

Phần lớn thời gian, stringlà loại bạn nên sử dụng - gần như tất cả các giao diện API lấy hoặc trả về chuỗi sẽ sử dụng nó. Tất cả các kiểu nguyên thủy của JS sẽ được gói ( đóng hộp ) với các loại đối tượng tương ứng của chúng khi sử dụng chúng làm đối tượng, ví dụ: truy cập các thuộc tính hoặc phương thức gọi. Vì Stringhiện được khai báo là một giao diện chứ không phải là một lớp trong thư viện lõi của TypeScript , gõ cấu trúc có nghĩa stringđược coi là một kiểu con trong Stringđó là lý do tại sao dòng đầu tiên của bạn vượt qua kiểm tra kiểu biên dịch.


2

Trong chuỗi JavaScript có thể là kiểu nguyên thủy chuỗi hoặc đối tượng chuỗi. Đoạn mã sau đây cho thấy sự khác biệt:

var a: string = 'test'; // string literal
var b: String = new String('another test'); // string wrapper object

console.log(typeof a); // string
console.log(typeof b); // object

Lỗi của bạn

Loại 'Chuỗi' không thể gán cho loại 'chuỗi'. 'Chuỗi' là một nguyên thủy, nhưng 'Chuỗi' là một đối tượng trình bao bọc. Thích sử dụng 'chuỗi' khi có thể.

Bị trình biên dịch TS ném vì bạn đã cố gán loại stringcho loại đối tượng chuỗi (được tạo thông qua newtừ khóa). Trình biên dịch đang nói với bạn rằng bạn chỉ nên sử dụng loại stringcho các kiểu nguyên thủy chuỗi và bạn không thể sử dụng loại này để mô tả các loại đối tượng chuỗi.


1

TypeScript: Stringvsstring

Đối số của loại 'Chuỗi' không thể gán cho tham số của loại 'chuỗi'.

'Chuỗi' là một nguyên thủy, nhưng 'Chuỗi' là một đối tượng trình bao bọc.

Thích sử dụng 'chuỗi' khi có thể.

bản giới thiệu

Chuỗi đối tượng

// error
class SVGStorageUtils {
  store: object;
  constructor(store: object) {
    this.store = store;
  }
  setData(key: String = ``, data: object) {
    sessionStorage.setItem(key, JSON.stringify(data));
  }
  getData(key: String = ``) {
    const obj = JSON.parse(sessionStorage.getItem(key));
  }
}

chuỗi nguyên thủy

// ok
class SVGStorageUtils {
  store: object;
  constructor(store: object) {
    this.store = store;
  }
  setData(key: string = ``, data: object) {
    sessionStorage.setItem(key, JSON.stringify(data));
  }
  getData(key: string = ``) {
    const obj = JSON.parse(sessionStorage.getItem(key));
  }
}

nhập mô tả hình ảnh ở đây


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.