暮年|细数这些年被困扰过的 TS 问题( 七 )
该行为是由按位运算引起的 。 有时 SomeFlag.Foo | SomeFlag.Bar 用于生成另一个 SomeFlag 。 相反 , 你最终得到的是数字 , 并且你不想强制回退到 SomeFlag 。
了解完上述内容 , 我们再来看一下 let value: Fonum = 12; 这个语句 , 该语句 TS 编译器不会报错 , 是因为数字 12 是可以通过 Fonum 已有的枚举成员计算而得 。
let value: Fonum =Fonum.a << Fonum.b << Fonum.a |Fonum.a << Fonum.b; // 12
继续阅读:5000 多字 , 让你一文掌握 TS 枚举九、使用 # 定义的私有字段与 private 修饰符定义字段有什么区别在 TypeScript 3.8 版本就开始支持 ECMAScript 私有字段 , 使用方式如下:
class Person {#name: string;constructor(name: string) {this.#name = name;}greet() {console.log(`Hello, my name is ${this.#name}!`);}}let semlinker = new Person("Semlinker");semlinker.#name;//~~~~~// Property '#name' is not accessible outside class 'Person'// because it has a private identifier.
与常规属性(甚至使用 private 修饰符声明的属性)不同 , 私有字段要牢记以下规则:
- 私有字段以 # 字符开头 , 有时我们称之为私有名称;
- 每个私有字段名称都唯一地限定于其包含的类;
- 不能在私有字段上使用 TypeScript 可访问性修饰符(如 public 或 private);
- 私有字段不能在包含的类之外访问 , 甚至不能被检测到 。
class Person {constructor(private name: string){}}let person = new Person("Semlinker");console.log(person.name);
在上面代码中 , 我们创建了一个 Person 类 , 该类中使用 private 修饰符定义了一个私有属性 name , 接着使用该类创建一个 person 对象 , 然后通过person.name 来访问 person 对象的私有属性 , 这时 TypeScript 编译器会提示以下异常:Property 'name' is private and only accessible within class 'Person'.(2341)
那如何解决这个异常呢?当然你可以使用类型断言把 person 转为 any 类型:console.log((person as any).name);
通过这种方式虽然解决了 TypeScript 编译器的异常提示 , 但是在运行时我们还是可以访问到 Person 类内部的私有属性 , 为什么会这样呢?我们来看一下编译生成的 ES5 代码 , 也许你就知道答案了:var Person = /** @class */ (function () {function Person(name) {this.name = name;}return Person;}());var person = new Person("Semlinker");console.log(person.name);
这时相信有些小伙伴会好奇 , 在 TypeScript 3.8 以上版本通过 # 号定义的私有字段编译后会生成什么代码:class Person {#name: string;constructor(name: string) {this.#name = name;}greet() {console.log(`Hello, my name is ${this.#name}!`);}}
以上代码目标设置为 ES2015 , 会编译生成以下代码:"use strict";var __classPrivateFieldSet = (this}privateMap.set(receiver, value);return value;};var __classPrivateFieldGet = (this}return privateMap.get(receiver);};var _name;class Person {constructor(name) {_name.set(this, void 0);__classPrivateFieldSet(this, _name, name);}greet() {console.log(`Hello, my name is ${__classPrivateFieldGet(this, _name)}!`);}}_name = new WeakMap();
通过观察上述代码 , 使用 # 号定义的 ECMAScript 私有字段 , 会通过 WeakMap 对象来存储 , 同时编译器会生成 __classPrivateFieldSet 和 __classPrivateFieldGet 这两个方法用于设置值和获取值 。
推荐阅读
- 暮年|构建 AI 新生态,“软件定义”摄像机打造机器智能新捷径
- 暮年|唯一一款7英寸5G手机,发布受到质疑,却意外收获好评
- 苹果手机|从多摄到快充,和你聊聊苹果手机这些年“借鉴”安卓的设计
- 暮年|谷歌结合物理模拟与机器学习方法,改进洪水预测速度与准确度
- 暮年|从华为这三位离职牛人高管可以看出,平台往往比能力更重要
- 暮年|这次美国运营商笑不出来了,126亿!替换华为和中兴代价有点高
- 暮年|126亿!替换华为和中兴代价有点高,这次美国运营商笑不出来了
- 娱乐中的趣闻|带领TES冲击S赛!,细数阿水在ig所受的委屈?怪不得恩断义绝
- 暮年|别老想弯道超车,新手上路小心翻车,发展半导体科技
- |前阿根廷国脚巴桑塔宣布退役:感谢大家这些年的支持和帮助