十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
是的,nextSibling方法可以用来获取某个元素的下一个兄弟元素,也就是说同层次元素中的下一个元素.注意一定要是兄弟元素.所谓的兄弟元素就是都被包含在同一个父元素中的元素.如果没有找到下一个兄弟元素,该方法则返回null.
创新互联公司专注于企业成都营销网站建设、网站重做改版、石棉网站定制设计、自适应品牌网站建设、HTML5建站、商城网站开发、集团公司官网建设、外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为石棉等各大城市提供网站开发制作服务。
比如有一组div或li元组,我们要获取某个div后面的那个div,就可以使用nextSibling方法来实现.或者获取某个li元素后面的那个元素.
Typescript 是 javascript 的类型超集,旨在简化大型 JavaScript 应用程序的开发。Typescript 加入了常见的概念例如 类(classes),泛型(generics),接口(interfaces)和静态类型(static types)并允许开发人员使用静态检查和代码重构等工具。
为什么在意 Typescript
现在问题仍然是为什么你应该优选使用 Typescript。这有一些关于为什么 javascript 开发者应该考虑学习 Typescript 的原因。
静态类型
Javascript 是动态类型的,这意味着直到在运行时实例化时,它不知道变量的类型,这可能导致项目中的问题和错误。Typescript 加入了对 Javascript 静态类型支持如果你正确的使用它处理由变量类型的错误设定引起的错误。您仍然可以完全控制输入代码的严格程度,或者甚至根本不使用类型。
更好的 IDE 支持
Typescript 相比 Javascript 一个更大的优势是更好的 IED 支持包括了来自 Typescript 编译器智能,实时的提示,调试以及更多功能。这里还有一大堆扩展进一步 提升你的 Typescript 开发体验。
应用新的 ECMAScript 特性
Typescript 使您可以使用最新的 ECMAScript 功能,并将它们转换到您选择的 ECMAScript 目标。这意味着您可以使用最新的工具开发应用程序,而无需担心浏览器支持。
什么时候你该使用它
到目前为止,我们应该知道为什么 Typescript 是有用的以及如何改善我们的开发体验。但它并不是解决所有问题的方法,当然也不能阻止你自己编写可怕的代码。那么让我们来看看你应该在哪里使用 Typescript。
当你拥有一个很大的代码库时
Typescript 是大型代码库的一个很好的补充,因为它可以帮助您防止许多常见错误。这尤其适用于多个开发人员工作在同一项目之中。
当你项目成员早已知道静态类型语言时
另一个明显使用 Typescript 的场景是当你和你的团队已经知道静态类型的语言像 Java 和 C# 不想改为编写 Javascript。
设置/建立
要设置 typescript,我们只需要使用 npm 包管理器安装它并创建一个新的 Typescript 文件。
安装完成之后我们可以继续探寻 Typescript 提供给我们的语法和功能特性。
类型
现在让我们来看看 Typescript 所提供的类型:
数值(Number)
Typescript 所有的值类型都是浮点数。所有的数字包括二进制和十六进制都是数值类型。
字符串(String)
与其他语言一样,Typescript 使用 String 数据类型来保存文本数据。
你还可以用反引号来应用多行字符串并嵌入表达式。
布尔类型(Boolean)
Typescript 支持所有的基本数据类型,布尔类型,值必须为 true 或者 false。
指定类型
现在我们已经有了基本的数据类型,我们可以看看你如何在 Typescript 中指定类型。基本上,您只需要在名称和冒号后面写出变量的类型。
单一类型
这里例子为我们如何为变量指定字符串数据类型
所有其他数据类型也是这样使用。
多类型
你仍然可以通过 | 操作符为你的变量指定多个数据类型:
这里我们使用|为变量分配两种类型。现在我们可以在其中存储字符串和数值。
类型检测
现在让我们看看我们如何检查我们的变量是否具有正确的类型。我们有多种选择,但在这里我只展示了两个最常用的选项。
Typeof
typeof 仅仅知道基本类型。这意味着它只能检查变量是否是我们上面定义的数据类型之一。
在此示例中,我们创建一个字符串类型变量并使用 typeof 命令检查 str 是否为 Number 类型(始终为 false)。然后我们打印是否是数值。
Instanceof
instanceof 运算符与 typeof 几乎相同,只是它还可以检查 javascript 尚未定义的自定义类型。
在这里,我们创建一个自定义类型,我们稍后将在本文中讨论,然后创建它的实例。之后,我们检查它是否真的是 Human 类型的变量,如果是,则在控制台中打印。
类型断言
有时我们还需要将变量转换为特定的数据类型。这经常发生在你已经指定了一个泛型类型像 any 并且你想使用它具体的类型的方法。
有很多选择可以解决这个问题,但在这里我只分享其中两个。
As 关键字
通过在变量名之后使用 as 关键字跟随具体的数据类型来转换变量的类型。
这里我们将 str 变量转换为字符串,以便我们可以使用 length 属性(如果您的 TSLINT 设置允许,甚至可以在没有转换的情况下工作)。
操作符
我们也可以使用 运算符,它与 as 关键字具有完全相同的效果,只有语法差异。
此代码块与上面的代码块具有完全相同的功能。它只是语法不同。
数组
Typescript 中的数组是相同对象的集合,可以用两种不同的方式创建。
创建数组
使用 []
我们可以通过指定类型后跟 [] 来定义数组对象,以表示它是一个数组。
在这个例子中,我们创建一个字符串数组,它包含三个不同的字符串值。
使用泛型数组
我们还可用指定 Array 定义泛型数组
这里我们创建一个数值数组,它包含 5 个不同的数字。
多(混合)类型数组
此外,我们还可以使用 | 操作符将多个类型分配给单个数组。
此例中我们创建了一个数值可以包含字符串和数值。
多维数组
Typescript 还允许我们定义多维数组,这意味着我们可以将数组保存在另一个数组中。我们可以通过使用多个[]运算符来创建一个多维数组。
这里我们创建一个包含另一个数字数组的数组。
元组(Tupels)
元组基本类似数组但有一点不同。我们可以定义每个位子上储存数据的类型。这意味着我们可以通过方括号内的枚举来限制固定索引位置的类型。
在此列中,我们定义了一个简单的元组,在索引 0 位置上指定为数值类型,在索引为 1 位置上指定为字符串类型。这意味着如果我们尝试在此索引上放置另一种数据类型,则会抛出错误。
以下是非法元组的示例:
枚举(Enums)
与大多数其他面向对象编程语言一样,Typescript 中的枚举允许我们定义一组命名常量。 Typescript 还提供基于数值和基于字符串的枚举。使用 enum 关键字定义 Typescript 中的枚举。
数值枚举
首先,我们将查看数值枚举,其中我们将键值与索引匹配。
上面,我们定义了数值枚举将 Playing 初始化为 0,Paused 为 1 等等。
我们也可以将初始化器留空,而 Typescript 会从零开始自动索引它。
字符串枚举
定义字符串枚举也十分简单,我们只需要在定义的每个枚举值后初始化字符串值。
这里我们通过使用字符串初始化我们的状态来定义字符串枚举。
对象(Objects)
Typescript 中的对象是包含一组键值对的实例。这些值可以是变量,数组甚至函数。它也被视为表示非基本类型的数据类型。
我们可以使用大括号创建一个对象:
这里我们创建了一个 human 对象包含三个不同的键值对。
我们可以为对象加入方法:
自定义类型
Typescript 还允许我们自定义类型,以便于我们后续重用。要创建自定义类型,我们只需要使用 type 关键字并定义我们的类型。
在此示例中,我们定义了一个名为 Human 包含三个属性的自定义类型。现在让我们看看如何创建这种类型的对象。
在这里,我们创建自定义类型的实例并设置所需的属性。
方法参数和返回类型
Typescript 允许我们为方法参数和返回值指定数据类型。现在让我们看一下使用 Typescript 定义函数的语法。
这里我们有两个示例函数,它们都具有定义类型的参数。我们还看到在结束括号后定义返回类型。
现在我们可以像普通的 javascript 一样调用我们的函数,但编译器会检查我们是否为函数提供了正确的参数。
可选属性
Typescript 允许我们为方法(注:接口等同样可以定义可选属性)定义可选属性。我们通过 ? 操作符定义。
在这个例子中,lastName 是一个可选参数,这意味着当我们不提供调用函数时,我们不会从编译器中获得错误。
这表示 2 个示例都被视为正确的。
默认值
我们使用可选属性的第二种方法是为它指定一个默认值。我们可以通过直接在函数头部赋值来实现。
在此例我中我们 lastName 赋予了默认值这意味着我们不必每次调用方法时提供它。
接口(Interfaces)
让我们看个例子让定义更加清晰:
可选属性
在 Typescript 中,有时并不是所有接口属性都是必需的。可以使用 ? 运算符在属性后面将其设置为可选。
在这里,我们创建一个具有一个普通和一个可选属性的接口,该属性是使用 ? 运算符。这就是我们两个人初始化都有效的原因。
只读属性
我们的接口中一些属性也应该只在首次创建对象时修改赋值。我们可以通过将 readonly 关键字放在我们的属性名称之前来指定此功能。
在此示例中,id 属性是只读的,在创建对象后无法更改。
模块(Barrels Modules)
Barrels 允许我们在一个更方便的模块中汇总多个导出模块。
我们仅需要创建一个新文件,它将导出我们项目中的多个模块 (译者注:根据 ECMAScript 定义一个文件定义一个模块,此处可能表示模块聚合(类似库等的入口文件))。
之后我们可以通过这个便利的单一导入语句引入这些模块。
泛型(Generics)
泛型允许我们创建兼容广泛类型而不是单一类型的组件。这使得我们的组件“ 开放”和复用。
现在您可能想知道为什么我们不只是使用任何( any )类型来使组件接受多种类型而不是单一类型。让我们看一个例子更好地了解。
我们想要一个简单的假函数(dummy function),它返回传入的参数:
然而 any 是通用的,某种程度它能接受所有类型参数但有一个很大的区别。我们丢失了我们传入的参数是什么类型以及返回值是什么类型。
所以让我们来看看,我们如何接受所有类型并知道它返回值的类型。
这里我们使用泛型参数 T,因此我们可以捕获变量类型并在以后使用它。我们还使用它作为返回参数类型,它允许我们在检查代码时看到相应的类型。
更多详细介绍你可以查看Charly Poly关于Generics and overloads的文章
访问修饰符(Access Modifiers)
访问修饰符控制我们类成员的可访问性。 Typescript 支持三种访问修饰符 - 公共的(public),私有的(private)和受保护的(protected)。
公共的
公共成员可以在任何地方访问,没有任何限制 这也是标准修饰符,这意味着您不需要使用 public 关键字为变量添加前缀。
私有的
私有成员只能在其定义的类中能访问。
受保护的
保护成员只能在其定义的类及其子类中访问。
TSLINT
TSLINT 是 Typescript 的标准 linter,可以帮助我们编写干净,可维护和可读的代码。它可以使用我们自己的 lint 规则,配置和格式化程序进行自定义。
设置
首先我们需要安装 Typescript 和 tslint,我们可以全局安装和局部安装:
之后,我们可以使用 TSLINT CLI 在我们的项目中初始化 TSLINT。
现在我们有了 tslint.json 文件,我们可以开始配置我们的规则了。
配置
TSLINT 允许使用配置我们自己的规则并自定义代码的外观。默认情况下,tslint.json 文件看起来像这样,只使用默认规则。
我们可以通过将它们放在 rules 对象中来添加其他规则。
有关所有可用规则的 概述,您可以查看官方文档。
结论
恭喜您一路走到最后!希望此篇文章帮助您理解 Typescript 的基础知识以及如何在项目中使用。
如果您发现这个有用,请考虑推荐并与其他开发人员共享。也可以访问我的网站学习更多。
如果您有任何问题和反馈,在以下评论中让我知道。
新系列 深入浅出TypeScript 来了,本系列至少20+篇。本文为第一篇,来介绍一下TypeScript 以及常见的类型。
TypeScript是一门由微软推出的开源的、跨平台的编程语言。它是JavaScript的超集,扩展了 JavaScript 的语法,最终会被编译为JavaScript代码。
TypeScript的主要特性:
TypeScript 主要是为了实现以下两个目标:
下面就来看看这两个目标是如何实现的。
为什么要给JavaScript加上类型呢?
我们知道,JavaScript是一种轻量级的解释性脚本语言。也是弱类型、动态类型语言,允许隐式转换,只有运行时才能确定变量的类型。正是因为在运行时才能确定变量的类型,JavaScript代码很多错误在运行时才能发现。TypeScript在JavaScript的基础上,包装了类型机制,使其变身成为 静态类型 语言。在 TypeScript 中,不仅可以轻易复用 JavaScript 的代码、最新特性,还能使用可选的静态类型进行检查报错,使得编写的代码更健壮、更易于维护。
下面是 JavaScript 项目中最常见的十大错误,如果使用 TypeScript,那么在 编写阶段 就可以发现并解决很多 JavaScript 错误了:
类型系统能够提高代码的质量和可维护性,经过不断的实践,以下两点尤其需要注意:
可以认为,在所有操作符之前,TypeScript 都能检测到接收的类型(在代码运行时,操作符接收的是实际数据;在静态检测时,操作符接收的则是类型)是否被当前操作符所支持。当 TypeScript 类型检测能力覆盖到所有代码后,任意破坏约定的改动都能被自动检测出来,并提出类型错误。因此,可以放心地修改、重构业务逻辑,而不用担忧因为考虑不周而犯下低级错误。
在一些语言中,类型总是有一些不必要的复杂的存在方式,而 TypeScript 尽可能地降低了使用门槛,它是通过如下方式来实现的。
TypeScript 与 JavaScript 本质并无区别,我们可以将 TypeScipt 理解为是一个添加了类型注解的 JavaScript,为JavaScript代码提供了编译时的类型安全。
实际上,TypeScript 是一门“ 中间语言 ”,因为它最终会转化为JavaScript,再交给浏览器解释、执行。不过 TypeScript 并不会破坏 JavaScript 原有的体系,只是在 JavaScript 的基础上进行了扩展。
准确的说,TypeScript 只是将JavaScript中的方法进行了标准化处理:
这段代码在TypeScript中就会报错,因为TS会知道a是一个数字类型,不能将其他类型的值赋值给a,这种类型的推断是很有必要的。
上面说了,TypeScript会尽可能安全的推断类型。我们也可以使用类型注释,以实现以下两件事:
在一些语言中,类型总是有一些不必要的复杂的存在方式,而 TypeScript 的类型是结构化的。比如下面的例子中,函数会接受它所期望的参数:
为了便于把 JavaScript 代码迁移至 TypeScript,即使存在编译错误,在默认的情况下,TypeScript 也会尽可能的被编译为 JavaScript 代码。因此,我们可以将JavaScript代码逐步迁移至 TypeScript。
虽然 TypeScript 是 JavaScript 的超集,但它始终紧跟ECMAScript标准,所以是支持ES6/7/8/9 等新语法标准的。并且,在语法层面上对一些语法进行了扩展。TypeScript 团队也正在积极的添加新功能的支持,这些功能会随着时间的推移而越来越多,越来越全面。
虽然 TypeScript 比较严谨,但是它并没有让 JavaScript 失去其灵活性。TypeScript 由于兼容 JavaScript 所以灵活度可以媲美 JavaScript,比如可以在任何地方将类型定义为 any(当然,并不推荐这样使用),毕竟 TypeScript 对类型的检查严格程度是可以通过 tsconfig.json 来配置的。
在搭建TypeScript环境之前,先来看看适合TypeScript的IDE,这里主要介绍Visual Studio Code,笔者就一直使用这款编辑器。
VS Code可以说是微软的亲儿子了,其具有以下优势:
因为 VS Code 中内置了特定版本的 TypeScript 语言服务,所以它天然支持 TypeScript 语法解析和类型检测,且这个内置的服务与手动安装的 TypeScript 完全隔离。因此, VS Code 支持在内置和手动安装版本之间动态切换语言服务,从而实现对不同版本的 TypeScript 的支持。
如果当前应用目录中安装了与内置服务不同版本的 TypeScript,我们就可以点击 VS Code 底部工具栏的版本号信息,从而实现 “use VS Code's Version” 和 “use Workspace's Version” 两者之间的随意切换。
除此之外,VS Code 也基于 TypeScript 语言服务提供了准确的代码自动补全功能,并显示详细的类型定义信息,大大的提升了我们的开发效率。
1)全局安装TypeScript:
2)初始化配置文件:
执行之后,项目根目录会出现一个 tsconfig.json 文件,里面包含ts的配置项(可能因为版本不同而配置略有不同)。
可以在 package.json 中加入script命令:
3)编译ts代码:
TSLint 是一个通过 tslint.json 进行配置的插件,在编写TypeScript代码时,可以对代码风格进行检查和提示。如果对代码风格有要求,就需要用到TSLint了。其使用步骤如下: (1)在全局安装TSLint:
(2)使用TSLint初始化配置文件:
执行之后,项目根目录下多了一个 tslint.json 文件,这就是TSLint的配置文件了,它会根据这个文件对代码进行检查,生成的 tslint.json 文件有下面几个字段:
这些字段的含义如下;
在说TypeScript数据类型之前,先来看看在TypeScript中定义数据类型的基本语法。
在语法层面,缺省类型注解的 TypeScript 与 JavaScript 完全一致。因此,可以把 TypeScript 代码的编写看作是为 JavaScript 代码添加类型注解。
在 TypeScript 语法中,类型的标注主要通过类型后置语法来实现:“ 变量: 类型 ”
在 JavaScript 中,原始类型指的是 非对象且没有方法 的数据类型,包括:number、boolean、string、null、undefined、symbol、bigInt。
它们对应的 TypeScript 类型如下:
JavaScript原始基础类型TypeScript类型 numbernumber booleanboolean stringstring nullnull undefinedundefined symbolsymbol bigIntbigInt
需要注意 number 和 Number 的区别:TypeScript中指定类型的时候要用 number ,这是TypeScript的类型关键字。而 Number 是 JavaScript 的原生构造函数,用它来创建数值类型的值,这两个是不一样的。包括 string 、 boolean 等都是TypeScript的类型关键字,而不是JavaScript语法。
TypeScript 和 JavaScript 一样,所有数字都是 浮点数 ,所以只有一个 number 类型。
TypeScript 还支持 ES6 中新增的二进制和八进制字面量,所以 TypeScript 中共支持 2、8、10和16 这四种进制的数值:
字符串类型可以使用单引号和双引号来包裹内容,但是如果使用 Tslint 规则,会对引号进行检测,使用单引号还是双引号可以在 Tslint 规则中进行配置。除此之外,还可以使用 ES6 中的模板字符串来拼接变量和字符串会更为方便。
类型为布尔值类型的变量的值只能是true或者false。除此之外,赋值给布尔值的值也可以是一个计算之后结果为布尔值的表达式:
在 JavaScript 中,undefined和 null 是两个基本数据类型。在 TypeScript 中,这两者都有各自的类型,即 undefined 和 null,也就是说它们既是实际的值,也是类型。这两种类型的实际用处不是很大。
注意,第一行代码可能会报一个tslint的错误: Unnecessary initialization to 'undefined' ,就是不能给一个变量赋值为undefined。但实际上给变量赋值为undefined是完全可以的,所以如果想让代码合理化,可以配置tslint,将" no-unnecessary-initializer "设置为 false 即可。
默认情况下,undefined 和 null 是所有类型的子类型,可以赋值给任意类型的值,也就是说可以把 undefined 赋值给 void 类型,也可以赋值给 number 类型。当在 tsconfig.json 的"compilerOptions"里设置为 "strictNullChecks": true 时,就必须严格对待了。这时 undefined 和 null 将只能赋值给它们自身或者 void 类型。这样也可以规避一些错误。
BigInt是ES6中新引入的数据类型,它是一种内置对象,它提供了一种方法来表示大于 2- 1 的整数,BigInt可以表示任意大的整数。
使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了JavaScript构造函数 Number 能够表示的安全整数范围。
我们知道,在 JavaScript 中采用双精度浮点数,这导致精度有限,比如 Number.MAX_SAFE_INTEGER 给出了可以安全递增的最大可能整数,即 2- 1 ,来看一个例子:
可以看到,最终返回了true,这就是超过精读范围造成的问题,而 BigInt 正是解决这类问题而生的:
这里需要用 BigInt(number) 把 Number 转化为 BigInt ,同时如果类型是 BigInt ,那么数字后面需要加 n 。
在TypeScript中, number 类型虽然和 BigInt 都表示数字,但是实际上两者类型是完全不同的:
symbol我们平时用的比较少,所以可能了解也不是很多,这里就详细来说说symbol。
symbol 是 ES6 新增的一种基本数据类型,它用来表示独一无二的值,可以通过 Symbol 构造函数生成。
注意:Symbol 前面不能加 new关键字,直接调用即可创建一个独一无二的 symbol 类型的值。
可以在使用 Symbol 方法创建 symbol 类型值的时候传入一个参数,这个参数需要是一个字符串。如果传入的参数不是字符串,会先自动调用传入参数的 toString 方法转为字符串:
上面代码的第三行可能会报一个错误:This condition will always return 'false' since the types 'unique symbol' and 'unique symbol' have no overlap. 这是因为编译器检测到这里的 s1 === s2 始终是false,所以编译器提醒这代码写的多余,建议进行优化。
上面使用Symbol创建了两个symbol对象,方法中都传入了相同的字符串,但是两个symbol值仍然是false,这就说明了 Symbol 方法会返回一个独一无二的值。Symbol 方法传入的这个字符串,就是方便我们区分 symbol 值的。可以调用 symbol 值的 toString 方法将它转为字符串:
在TypeScript中使用symbol就是指定一个值的类型为symbol类型:
在ES6中,对象的属性是支持表达式的,可以使用于一个变量来作为属性名,这对于代码的简化有很多用处,表达式必须放在大括号内:
symbol 也可以作为属性名,因为symbol的值是独一无二的,所以当它作为属性名时,不会与其他任何属性名重复。当需要访问这个属性时,只能使用这个symbol值来访问(必须使用方括号形式来访问):
在使用obj.name访问时,实际上是字符串name,这和访问普通字符串类型的属性名是一样的,要想访问属性名为symbol类型的属性时,必须使用方括号。方括号中的name才是我们定义的symbol类型的变量name。
使用 Symbol 类型值作为属性名,这个属性是不会被 for…in遍历到的,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 、 JSON.stringify() 等方法获取到:
虽然这些方法都不能访问到Symbol类型的属性名,但是Symbol类型的属性并不是私有属性,可以使用 Object.getOwnPropertySymbols 方法获取对象的所有symbol类型的属性名:
除了这个方法,还可以使用ES6提供的 Reflect 对象的静态方法 Reflect.ownKeys ,它可以返回所有类型的属性名,Symbol 类型的也会返回:
Symbol 包含两个静态方法, for 和 keyFor 。 1)Symbol.for()
用Symbol创建的symbol类型的值都是独一无二的。使用 Symbol.for 方法传入字符串,会先检查有没有使用该字符串调用 Symbol.for 方法创建的 symbol 值。如果有,返回该值;如果没有,则使用该字符串新创建一个。使用该方法创建 symbol 值后会在全局范围进行注册。
上面代码中,创建了一个iframe节点并把它放在body中,通过这个 iframe 对象的 contentWindow 拿到这个 iframe 的 window 对象,在 iframe.contentWindow上添加一个值就相当于在当前页面定义一个全局变量一样。可以看到,在 iframe 中定义的键为 TypeScript 的 symbol 值在和在当前页面定义的键为'TypeScript'的symbol 值相等,说明它们是同一个值。
2)Symbol.keyFor() 该方法传入一个 symbol 值,返回该值在全局注册的键名:
看完简单的数据类型,下面就来看看比较复杂的数据类型,包括JavaScript中的数组和对象,以及TypeScript中新增的元组、枚举、Any、void、never、unknown。
在 TypeScript 中有两种定义数组的方式:
以上两种定义数组类型的方式虽然本质上没有任何区别,但是更推荐使用第一种形式来定义。一方面可以避免与 JSX 语法冲突,另一方面可以减少代码量。
注意,这两种写法中的 number 指定的是数组元素的类型,也可以在这里将数组的元素指定为其他任意类型。如果要指定一个数组里的元素既可以是数值也可以是字符串,那么可以使用这种方式: number|string[] 。
在JavaScript中,object是引用类型,它存储的是值的引用。在TypeScript中,当想让一个变量或者函数的参数的类型是一个对象的形式时,可以使用这个类型:
可以看到,当给一个对象类型的变量赋值一个对象时,就会报错。对象类型更适合以下场景:
在 JavaScript 中并没有元组的概念,作为一门动态类型语言,它的优势是支持多类型元素数组。但是出于较好的扩展性、可读性和稳定性考虑,我们通常会把不同类型的值通过键值对的形式塞到一个对象中,再返回这个对象,而不是使用没有任何限制的数组。TypeScript 的元组类型正好弥补了这个不足,使得定义包含固定个数元素、每个元素类型未必相同的数组成为可能。
元组可以看做是数组的扩展,它表示已知元素数量和类型的数组,它特别适合用来实现多值返回。确切的说,就是已知数组中每一个位置上的元素的类型,可以通过元组的索引为元素赋值::
可以看到,定义的arr元组中,元素个数和元素类型都是确定的,当为arr赋值时,各个位置上的元素类型都要对应,元素个数也要一致。
当访问元组元素时,TypeScript也会对元素做类型检查,如果元素是一个字符串,那么它只能使用字符串方法,如果使用别的类型的方法,就会报错。
在TypeScript 新的版本中,TypeScript会对元组做越界判断。超出规定个数的元素称作越界元素,元素赋值必须类型和个数都对应,不能超出定义的元素个数。
这里定义了接口 Tuple ,它继承数组类型,并且数组元素的类型是 number 和 string 构成的联合类型,这样接口 Tuple 就拥有了数组类型所有的特性。并且指定索引为0的值为 string 类型,索引为1的值为 number 类型,同时指定 length 属性的类型字面量为 2,这样在指定一个类型为这个接口 Tuple 时,这个值必须是数组,而且如果元素个数超过2个时,它的length就不是2是大于2的数了,就不满足这个接口定义了,所以就会报错;当然,如果元素个数不够2个也会报错,因为索引为0或1的值缺失。
TypeScript 在 ES 原有类型基础上加入枚举类型,使得在 TypeScript 中也可以给一组数值赋予名字,这样对开发者比较友好。枚举类型使用enum来定义:
上面定义的枚举类型的Roles,它有三个值,TypeScript会为它们每个值分配编号,默认从0开始,在使用时,就可以使用名字而不需要记数字和名称的对应关系了:
除此之外,还可以修改这个数值,让SUPER_ADMIN = 1,这样后面的值就分别是2和3。当然还可以给每个值赋予不同的、不按顺序排列的值:
我们可以将一个值定义为any类型,也可以在定义数组类型时使用any来指定数组中的元素类型为任意类型:
any 类型会在对象的调用链中进行传导,即any 类型对象的任意属性的类型都是 any,如下代码所示:
需要注意:不要滥用any类型,如果代码中充满了any,那TypeScript和JavaScript就毫无区别了,所以除非有充足的理由,否则应该尽量避免使用 any ,并且开启禁用隐式 any 的设置。
void 和 any 相反,any 是表示任意类型,而 void 是表示没有类型,就是什么类型都不是。这在 定义函数,并且函数没有返回值时会用到 :
需要注意: void 类型的变量只能赋值为 undefined 和 null ,其他类型不能赋值给 void 类型的变量。
never 类型指永远不存在值的类型,它是那些 总会抛出异常 或 根本不会有返回值的函数表达式的返回值 类型,当变量被永不为真的类型保护所约束时,该变量也是 never 类型。
下面的函数,总是会抛出异常,所以它的返回值类型是never,用来表明它的返回值是不存在的:
never 类型是任何类型的子类型,所以它可以赋值给任何类型;而没有类型是 never 的子类型,所以除了它自身以外,其他类型(包括 any 类型)都不能为 never 类型赋值。
上面代码定义了一个立即执行函数,函数体是一个死循环,这个函数调用后的返回值类型为 never,所以赋值之后 neverVariable 的类型是 never 类型,当给neverVariable 赋值 123 时,就会报错,因为除它自身外任何类型都不能赋值给 never 类型。
基于 never 的特性,我们可以把 never 作为接口类型下的属性类型,用来禁止操作接口下特定的属性:
可以看到,无论给 props.name 赋什么类型的值,它都会提示类型错误,这就相当于将 name 属性设置为了只读 。
unknown 是TypeScript在3.0版本新增的类型,主要用来描述类型并不确定的变量。它看起来和any很像,但是还是有区别的,unknown相对于any更安全。
对于any,来看一个例子:
上面这些语句都不会报错,因为value是any类型,所以后面三个操作都有合法的情况,当value是一个对象时,访问name属性是没问题的;当value是数值类型的时候,调用它的toFixed方法没问题;当value是字符串或数组时获取它的length属性是没问题的。
当指定值为unknown类型的时候,如果没有 缩小类型范围 的话,是不能对它进行任何操作的。总之,unknown类型的值不能随便操作。那什么是类型范围缩小呢?下面来看一个例子:
这里由于把value的类型缩小为Date实例的范围内,所以进行了value.toISOString(),也就是使用ISO标准将 Date 对象转换为字符串。
使用以下方式也可以缩小类型范围:
关于 unknown 类型,在使用时需要注意以下几点:
在实际使用中,如果有类型无法确定的情况,要尽量避免使用 any,因为 any 会丢失类型信息,一旦一个类型被指定为 any,那么在它上面进行任何操作都是合法的,所以会有意想不到的情况发生。因此如果遇到无法确定类型的情况,要先考虑使用 unknown。
1.什么是JavaScript?
JavaScript是一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。通俗的讲JavaScript通常用来做网页的交互以及同动态效果。它是一种非常流行的脚本语言,是一种运行在浏览器中的解释型编程语言。
2.同源的定义:
如果两个页面的协议/端口和主机都相同,那么这两个页面具有相同的源。我们也可以把它称为“协议/主机/端口 tuple”,或简单地叫做“tuple". ("tuple" ,“元”,“元组”是指一些事物组合在一起形成一个整体,比如(1,2)叫二元,(1,2,3)叫三元)。下表给出了相对同源检测的示例:
(只是路径不同而已,同源。)
(只是路径不同,同源)
(协议不同,http≠https,不同源)
(端口不同,http://80是默认值,不同源)
(域名不同,news/store,不同源)
3.JavaScript可以对文本web文档内容进行操作,对文档随意操作是互联网世界大忌,因此要对其进行限制。针对代码可以限定对哪些特定的web文本进行操作,这就叫同源策略。
同源策略的含义:脚本只能读取和所属文档来源相同的窗口和文档的属性。
以上就是JavaScript同源策略的大致概念,若要深究同源的验证过程以及原理,可以自行系统完整的学习此概念,对自己大有裨益。