2013-09-23 46 views
106

Tôi nhìn vào mã nguyên cảo và nhận thấy rằng họ sử dụngnguyên cảo bất kỳ vs Object

interface Blablabla { 

    field: Object; 

} 

lợi ích của việc sử dụng Object vs bất kỳ là gì, như trong

interface Blablabla { 

    field: any; 

} 

Trả lời

109

Object là hạn chế hơn bất kỳ. Đó là:

interface MyInterface { 

    b: Object; 
} 

var foo = (a : MyInterface) => alert(a.b.nomethod()); 

sẽ không biên dịch vì Object không có một chức năng nomethod(). Nếu bạn sử dụng any trong giao diện thay vì Object thì nó sẽ biên dịch.

Vì vậy, trong ngắn hạn, any có thể là bất cứ điều gì (bạn có thể gọi bất kỳ phương pháp vv trên đó mà không có lỗi biên dịch). Nếu bạn sử dụng một cách rõ ràng Object, bạn sẽ chỉ có thể sử dụng các phương thức vv được xác định trên lớp Object.

+0

Tôi đang làm việc với tệp định nghĩa bên ngoài sử dụng Object. Có cách nào để mở rộng nó để trình biên dịch chấp nhận chuỗi? – Jay

12

Object dường như là một tuyên bố cụ thể hơn bất kỳ tuyên bố nào. Từ thông số TypeScript (phần 3):

Tất cả các loại trong TypeScript là kiểu con của một loại hàng đầu được gọi là Mọi loại. Bất kỳ từ khóa nào tham chiếu đến loại này. Loại Bất kỳ là loại có thể đại diện cho bất kỳ giá trị JavaScript nào không có ràng buộc. Tất cả các loại khác được phân loại là loại nguyên thủy, loại đối tượng hoặc thông số loại . Các loại này giới thiệu các ràng buộc tĩnh khác nhau trên giá trị của chúng.

Ngoài ra:

Các Bất kỳ loại được sử dụng để đại diện cho bất kỳ giá trị JavaScript. Giá trị của Bất kỳ loại nào hỗ trợ các hoạt động giống như một giá trị trong JavaScript và kiểm tra loại tĩnh tối thiểu được thực hiện cho các phép toán trên bất kỳ giá trị nào. Cụ thể, các thuộc tính của bất kỳ tên nào có thể được truy cập thông qua một Giá trị bất kỳ và Bất kỳ giá trị nào cũng có thể được gọi là hàm hoặc các hàm tạo với bất kỳ danh sách đối số nào.

Đối tượng không cho phép sự linh hoạt như nhau.

Ví dụ:

var myAny : any; 

myAny.Something(); // no problemo 

var myObject : Object; 

myObject.Something(); // Error: The property 'Something' does not exist on value of type 'Object'. 
+1

Tốt câu trả lời, có thể tốt hơn để hiển thị các thiếu linh hoạt – basarat

+2

Edited. Có lẽ không phải là sửa đổi tốt nhất, nhưng ít nhất là trung thực. :) –

22

any là một cái gì đó cụ thể cho TypeScript được giải thích khá tốt bằng câu trả lời của alex.

Object đề cập đến loại JavaScript object. Thường được sử dụng làm {} hoặc đôi khi new Object. Hầu hết mọi thứ trong javascript đều tương thích với loại dữ liệu đối tượng khi chúng kế thừa từ nó. Nhưng anyTypeScript cụ thể và tương thích với mọi thứ theo cả hai hướng (không dựa trên kế thừa). ví dụ. :

var foo:Object; 
var bar:any; 
var num:number; 

foo = num; // Not an error 
num = foo; // ERROR 

// Any is compatible both ways 
bar = num; 
num = bar; 
13

Trái ngược với.NET, nơi tất cả các loại xuất phát từ một "đối tượng", trong TypeScript, tất cả các loại xuất phát từ "bất kỳ". Tôi chỉ muốn thêm so sánh này vì tôi nghĩ rằng nó sẽ là một trong những phổ biến được thực hiện như nhiều hơn nữa. NET phát triển cho TypeScript một thử.

145

Bit cũ, nhưng không đau khi thêm một số ghi chú.

Khi bạn viết một cái gì đó như thế này

var a: any; 
var b: Object; 
var c: {}; 
  • một không có giao diện, nó có thể là bất cứ điều gì, trình biên dịch không biết gì về các thành viên của nó kiểm tra kiểu như vậy tối thiểu được thực hiện khi truy cập/gán cả chính nó và các thành viên của nó. Về cơ bản, bạn đang yêu cầu trình biên dịch trả về ", tôi biết mình đang làm gì, vì vậy hãy tin tôi";
  • b có giao diện Đối tượng, vì vậy CHỈ các thành viên được xác định trong giao diện đó có sẵn cho b. Nó vẫn là JavaScript, vì vậy mọi thứ mở rộng Object;
  • c mở rộng Object, giống như bất kỳ thứ gì khác trong TypeScript, nhưng không thêm thành viên nào. Vì kiểu tương thích trong TypeScript dựa trên kiểu con cấu trúc, không phải kiểu con danh nghĩa, c kết thúc giống như b vì chúng có cùng giao diện: giao diện Đối tượng.

Và đó là lý do tại sao

a.doSomething(); // Ok: the compiler trusts you on that 
b.doSomething(); // Error: Object has no doSomething member 
c.doSomething(); // Error: c neither has doSomething nor inherits it from Object 

và tại sao

a.toString(); // Ok: whatever, dude, have it your way 
b.toString(); // Ok: toString is defined in Object 
c.toString(); // Ok: c inherits toString from Object 

Vì vậy, cả hai Object{} là tương đương với nguyên cảo. Tôi không thấy ai thực sự sử dụng nó. Quá hạn chế.

Nếu bạn khai báo các chức năng như những

function fa(param: any): void {} 
function fb(param: Object): void {} 

với ý định chấp nhận bất cứ điều gì cho param (có lẽ bạn đang đi để kiểm tra các loại tại thời gian chạy để quyết định phải làm gì với nó), hãy nhớ rằng

  • bên fa, trình biên dịch sẽ cho phép bạn làm bất cứ điều gì bạn muốn với param;
  • bên fb, trình biên dịch sẽ chỉ cho phép bạn truy cập các thành viên đối tượng, và bạn sẽ kết thúc phải làm rất nhiều typecasting có ...

Vì vậy, về cơ bản, khi bạn không biết loại, đi với bất kỳ nào và thực hiện kiểm tra loại thời gian chạy.

Rõ ràng, các quy tắc OO thừa kế vẫn áp dụng, vì vậy nếu bạn muốn chấp nhận các trường hợp của các lớp thừa kế và đối xử với họ dựa trên loại hình cơ bản của họ, như trong

interface IPerson { 
    gender: string; 
} 

class Person implements IPerson { 
    gender: string; 
} 

class Teacher extends Person {} 

function func(person: IPerson): void { 
    console.log(person.gender); 
} 

func(new Person());  // Ok 
func(new Teacher()); // Ok 
func({gender: 'male'}); // Ok 
func({name: 'male'}); // Error: no gender.. 

kiểu cơ sở là cách để làm điều đó, không phải bất kỳ nào.Nhưng đó là OO, ngoài phạm vi, tôi chỉ muốn làm rõ rằng bất kỳ chỉ nên được sử dụng khi bạn không biết whats sắp tới, và cho bất cứ điều gì khác bạn nên chú thích các loại chính xác.

UPDATE:

Typescript 2.2 thêm một loại object, xác định rằng một giá trị là một tổ chức phi nguyên thủy: (ví dụ: không phải là một number, string, boolean, symbol, undefined, hoặc null).

Hãy xem xét các chức năng định nghĩa là:

function b(x: Object) {} 
function c(x: {}) {} 
function d(x: object) {} 

x sẽ có các thuộc tính có sẵn giống nhau trong tất cả các chức năng này, nhưng đó là một lỗi kiểu gọi d với bất cứ điều gì phi nguyên thủy:

b("foo"); //Okay 
c("foo"); //Okay 
d("foo"); //Error: "foo" is a primitive 
+2

Không ai biết * tại sao * họ quyết định thêm '{}' sau đó nếu họ đã có 'Object'? (hoặc ngược lại, tùy theo điều kiện nào đến trước) Có một số khác biệt nhỏ, phải không? – CletusW

+2

'{}' là cách thông thường để định nghĩa các giao diện (nội dòng), chỉ trong trường hợp này bạn định nghĩa một giao diện không có thành viên. Sự khác biệt nhỏ cũng được giải thích trong câu trả lời: "' {} 'mở rộng' Đối tượng', giống như bất kỳ thứ gì khác trong TypeScript ". – DanielM

+0

Tôi muốn bình chọn cho bạn về dòng _So, về cơ bản, khi bạn không biết loại, hãy đi với 'any' và kiểm tra kiểu thời gian chạy._ Không sử dụng' any', thay vào đó hãy sử dụng liên kết các loại bạn đang kiểm tra: 'TypeA | InterfaceB | string'. Nếu bạn cũng có một trường hợp mặc định cho một kiểu không xác định, hãy thêm '{}' hoặc 'Object' vào union. – ILMTitan

0

Thêm vào câu trả lời của Alex và đơn giản hóa câu trả lời của Alex:

Đối tượng nghiêm ngặt hơn với việc sử dụng của chúng và do đó cung cấp cho p thời gian biên dịch nhiều hơn "thẩm định" và do đó trong nhiều trường hợp cung cấp thêm "kiểm tra khả năng" và ngăn chặn bất kỳ rò rỉ nào, trong khi đó là một thuật ngữ chung chung hơn và nhiều lần kiểm tra biên dịch có thể bị bỏ qua.

0

thử điều này:

private a: Object<any> = {}; 

constructor() { 
    a.name = "foo"; 
} 
+0

Các câu trả lời chỉ có mã không được khuyến khích vì chúng không giải thích cách chúng giải quyết vấn đề. Vui lòng cập nhật câu trả lời của bạn để giải thích cách điều này cải thiện trên các câu trả lời được chấp nhận và được bình chọn khác mà câu hỏi này đã có. Ngoài ra, câu hỏi này là 4 tuổi, nỗ lực của bạn sẽ được đánh giá cao hơn bởi những người dùng có câu hỏi chưa được trả lời gần đây. Vui lòng xem lại [Làm cách nào để viết câu trả lời hay] (https://stackoverflow.com/help/how-to-answer). – FluffyKitten

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