【问题标题】:Object versus casted literal object in TypeScriptTypeScript 中的对象与强制转换的文字对象
【发布时间】:2016-09-14 21:19:22
【问题描述】:

我真的不知道什么时候用这个:

interface IFoo
{
   bar: string;
}

...

let array: IFoo[];

array.push(<IFoo>{ bar: "test" });

或者

class Foo
{
   bar: string;
}

...

let array: Foo[];
let obj = new Foo();

obj.bar = "test";

array.push(obj);

事情是我来自 C# 世界,对我来说,第二种方式更干净,但使用第一种方式也很诱人,尽管它不像第二种选择那么严格。因此,我真的很挣扎,目前,我只是觉得我可以使用我想要的那个,但我很确定它们都有优点和缺点。不幸的是,我在谷歌上找不到任何东西。

谢谢

【问题讨论】:

  • 你为什么要在第一个例子中投射?没必要
  • 确实是这样,但问题仍然有效;-)
  • 如果你只想拥有一个具有属性的对象,那么选择接口的第一个选项,但如果你想拥有该对象的方法,那么就使用一个类
  • @NitzanTomer 的改写:当你想描述数据时使用接口。当您想要提供一个实现(不由服务或外部函数处理)时,请使用类。

标签: typescript


【解决方案1】:

在 javascript 中,我们实际上没有类,而只有具有原型功能的普通对象*(“哈希表”-y)。函数是某种对象(上面有一点语法糖)。

*(学术上不正确的说法,并隐瞒了一些事情)

在浏览器的调试器中尝试下面的例子,做一些检查

var parent = {
   method1: function() { return 1 } ,
   method2: function() { return 2 }
}
var child = Object.create(parent)
child.method2 = function() { return '2a' }

child.__proto__   //shows parent
parent.__proto__  //shows Object (the "root class")
child.method3()   //undefined is not a function
child.method2()   //2a, not 2
child.method1()   //method1 not found, looks at __proto__, returns 1
child.toString    
//looks at child, not found
//looks at child.__proto__ (parent), not found
//looks at child.__proto__.__proto__ (Object), returns function

类(来自 ES2015 和转译器)大致做的是消除您必须编写的一些胶水代码,以便从其他语言(从对象和原型开始)获得 class 行为/编程风格。

在 ES2015 中,类声明创建一个“原型”对象,new(或 Object.create**)创建一个继承该原型的“实例”对象。

现在回到打字稿...

var a : { b : string }
a.b = '4'

{ b : string } 只是一个注解。它进入了类型的领域。假设在打字稿中,我们有 2 个领域,即具体变量的领域,最终进入生成的代码;和类型的领域,它们仅用于辅助/linting,但不会最终出现在真正的 JS 中。 { b : string } 可以使用 interfacetype 语法来引用

type Ta = { b : string } //or
interface Ta { b : string }
var a : Ta

声明类型注释(包括接口)将零代码添加到具体的 JS 领域。

..另一方面,当您使用 class 时,typescript 会同时创建两者

  • 具体的JS代码(即原型对象)
  • 还有几个类型的领域居民。

TL;DR:

现在回答一下,这两种方式中的任何一种都没有大问题,但是使用接口(和更少的类)倾向于最常见的 javascript 编码风格。一些 JS 学校不提倡使用类,因为你可以通过其他模式大多达到相同的效果。

【讨论】:

  • 好的,所以当我需要包含方法和普通对象的高级对象时,一个有效的方法是使用类而不是这种情况?感谢您的解释:-P
  • 大多是这样。越简单越好。
【解决方案2】:

我认为这两个示例都会失败,因为您没有初始化array 的值,只是为其声明了一个类型。你需要像这样初始化它:

let array : Array<IFoo> = [];
array.push( {bar: "test" } );

在定义其他成员(如方法或计算属性)之前,使用类的优势并不显着。在这种情况下,您需要使用new Foo(...)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多