any 和 any[ ] 有啥区别?
Posted
技术标签:
【中文标题】any 和 any[ ] 有啥区别?【英文标题】:What is the difference between any and any[ ]?any 和 any[ ] 有什么区别? 【发布时间】:2017-10-19 12:59:30 【问题描述】:any和any[ ]有什么区别?
示例 1(按预期工作)
name1: any;
name2: any[];
this.name1 = this.name2;
示例 2(这也按预期工作)
name1: any;
name2: any[];
this.name2 = this.name1;
为什么允许
any
数据类型的打字稿可以访问any[]
数据类型。和any[]
一样的数据类型可以访问any
类型的数据吗?和哪个最好用?和如果数据类型只是像string or number or object or any
这样的对象(不是数组),那么为什么any[ ]
会接受该对象类型而不显示任何运行时或编译时错误?。
【问题讨论】:
好吧..它可以是任何东西或任何东西的数组(这有点没有意义,因为任何东西也可以是任何东西的数组)。 any 类型是禁用代码位类型检查的打字稿方式。 是的,这是您在使用 typescript 时可能遇到的唯一问题 我认为这是个好问题。应该是编译时错误,至少对于 noImplicitAny。然而,打字稿团队似乎愿意放宽类型严格性以支持现有代码。不利于语言恕我直言。 【参考方案1】:如果我们看一下这个 TypeScript 代码:
let name1: any = "John";
let name2: any[] = ["Mary", "Sue", "Sally"];
name1 = name2;
let name3: any[] = ["Luke", "Paul", "Ringo"];
let name4: any = "Mark";
name3 = name4;
它编译成的javascript是:
var name1 = "John";
var name2 = ["Mary", "Sue", "Sally"];
name1 = name2;
var name3 = ["Luke", "Paul", "Ringo"];
var name4 = "Mark";
name3 = name4;
JavaScript 变量是动态的,没有固定类型。我可以想象这个可能会被 TypeScript 编译器报告为警告或错误,但这不会停止 JavaScript 的生成或阻止 JavaScript 运行。
因此,虽然any
/any[]
分配当前没有编译错误或警告,但any[]
仍可用于告知开发人员期望。
注意:这不是我会编写或建议任何人使用的代码。这只是带有值的 OP 代码,并显示了生成的 JavaScript 将是什么,并且因为它编译为 JavaScript,所以不会因类型而出现运行时错误,因为变量具有动态类型。这也是我们选择使用 TypeScript 的原因之一:编译时静态类型检查。出于这个原因,人们通常会避免使用any
和any[]
来支持更好地表示数据的类或接口。在这种情况下,string
与 string[]
(或任何其他类型)将显示编译器错误。
在此示例中,name1 = name2
和 name3 = name4
都是编译时错误,因为变量从赋值中推断类型,并且它们的用法在后续代码中进行类型检查。
let name1 = "John";
let name2 = ["Mary", "Sue", "Sally"];
name1 = name2; //Type 'string[]' is not assignable to type 'string'.
let name3 = ["Luke", "Paul", "Ringo"];
let name4 = "Mark";
name3 = name4; //Type 'string' is not assignable to type 'string[]'.
【讨论】:
说得好。一个很好的答案。【参考方案2】:如果你在赋值的左边和右边都使用any
,你基本上是说Typescript不使用类型检查。
any
位于左侧,这意味着您要分配值的变量可以接受任何类型,因此它接受任何类型的对象,包括 any[]
类型的对象。
如果 any
类型在右侧,而 myVar: any[]
在左侧,则基本上是说 Typescript 不使用类型检查。考虑到在运行时不应用类型检查,您最终会得到 myVar
被填满作业右侧的任何内容。
【讨论】:
是的!但我非常谦虚的问题是。如果数据不是数组,它只是一个对象,那么为什么 any[] 将接受该类型?至少它应该抛出一个运行时错误?但不是,为什么? @RameshRajendran,因为它编译为 Javascript,你怎么会期望出现运行时错误(变量没有静态类型)?【参考方案3】:-
仅 Any 用于任何类型的单个对象。
Any[] 用于 Any 类型的对象数组。
【讨论】:
【参考方案4】:any 和 any[] 的区别在于智能。
var a:any = .....
a.map , a.join (no intellisense, typescript does not know if a is an array or not)
var a:any[] = ....
a.map , a.join (typescript knows that a is an array and will provide intellisence)
编译时错误
var aa:any[] = "a"; // error typescript will not allow this
var a:any = "a"; // a can be string, there is no harm
aa = a; // typescript cannot detect error at
// compile time because a can be array
var someString:string;
aa = someString; // typescript knows that aa is an array and someString is not
通过声明any[]
,您是在告诉我我希望这个对象是数组类型。然而,any 就是任何东西,甚至数组也可以是 any
,所以 typescript 允许您将 any 分配给任何数组。
TypeScript 会尽可能检测编译时错误,但是当您将某些内容设置为 any 时,它不会检测到编译时错误。
编译器设计者是否强制执行此类编译时错误,我想不应该允许以下操作,
a:any
aa:any[] = a; // this should be compile time error
为避免这种情况,当然可以将其转换为 aa = a as any[]
,就像在 C# 和 Java 等语言中一样。
运行时错误
JavaScript 没有关于变量声明的类型规范,因此 JavaScript 引擎对类型没有任何概念。
只有当你调用一个方法或访问属性时,JavaScrip 才会给你一个错误..
a:any[] ..
// this will give an error TypeError: .map is not a function
a.map( ()=> ... )
a.length // this is undefined.. any member of any object is
// essentially undefined, there is no type error when you access
// member
【讨论】:
以上是关于any 和 any[ ] 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
Mockito Matchers isA、any、eq 和 same 有啥区别?
Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有啥区别?
TypeScript 中 unknown 与 any 有啥区别
Array 和 Observable Array 有啥区别?