前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原来 js 跟 ts 也有相识之处

原来 js 跟 ts 也有相识之处

作者头像
公众号---人生代码
发布2021-04-22 11:28:31
1.5K0
发布2021-04-22 11:28:31
举报
文章被收录于专栏:人生代码人生代码

JavaScript私有类字段和隐私的需要

闭包是保护变量不被访问的唯一JavaScript原生机制。

闭包是许多类似私有模式的基础,比如流行的模块模式。但在ECMAScript 2015 classes近年来接管之后,开发人员感到有必要对classes成员的隐私进行更多的控制。

class field提案(在第三阶段写作时)试图通过引入私有类字段来解决这个问题。

让我们看看它们是什么样的。

JavaScript私有类字段,一个例子

这里有一个带有私有字段的JavaScript类,注意,与“公共”成员不同,每个私有字段必须在访问之前声明:

代码语言:javascript
复制
class Person {
  #age;
  #name;
  #surname;

  constructor(name, surname, age) {
    this.#name = name;
    this.#surname = surname;
    this.#age = age;
  }

  getFullName() {
    return `${this.#name} + ${this.#surname}`;
  }
}

私有类字段不能从类外部访问:

代码语言:javascript
复制
class Person {
  #age;
  #name;
  #surname;

  constructor(name, surname, age) {
    this.#name = name;
    this.#surname = surname;
    this.#age = age;
  }

  getFullName() {
    return `${this.#name} + ${this.#surname}`;
  }
}

const marta = new Person("Marta", "Cantrell", 33);
console.log(marta.#age); // SyntaxError

这才是真正的“隐私”。现在,如果你使用了一些TypeScript,你可能会问“原生”私有字段和TypeScript中的私有修饰符有什么共同之处。

答案是:什么都没有。但是为什么呢?

TypeScript中的私有修饰符

来自传统背景的开发者应该熟悉TypeScript中的私有修饰符。简而言之,关键字意味着拒绝类成员从类外部访问。

但别忘了,TypeScript是在JavaScript之上的一层,TypeScript编译器应该去掉所有花哨的TypeScript注释,包括private。

这意味着下面的类不会做你认为它会做的事情:

代码语言:javascript
复制
class Person {
  private age: number;
  private name: string;
  private surname: string;

  constructor(name: string, surname: string, age: number) {
    this.name = name;
    this.surname = surname;
    this.age = age;
  }

  getFullName() {
    return `${this.name} + ${this.surname}`;
  }
}

const liz = new Person("Liz", "Cantrill", 31);
// @ts-ignore
console.log(liz.age);

没有// @ts-ignore,访问liz。age只会在TypeScript中抛出错误,但编译后你会得到以下JavaScript代码:

代码语言:javascript
复制
"use strict";
var Person = /** @class */ (function () {
    function Person(name, surname, age) {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }
    Person.prototype.getFullName = function () {
        return this.name + " + " + this.surname;
    };
    return Person;
}());

var liz = new Person("Liz", "Cantrill", 31);
console.log(liz.age); // 31

不出所料,我们可以随意刊登莉兹的年龄。这里的主要观点是,TypeScript中的private并不是那么私密,它只在TypeScript级别上使用,而不是“真正的隐私”。

现在让我们来看看要点:TypeScript中的“原生”私有类字段。

TypeScript中的私有类字段

TypeScript 3.8增加了对ECMAScript私有字段的支持,不要与TypeScript私有修饰符混淆。

下面是TypeScript中一个带有私有类字段的类:

代码语言:javascript
复制
class Person {
    #age: number;
    #name: string;
    #surname: string;

    constructor(name:string, surname:string, age:number) {
        this.#name = name;
        this.#surname = surname;
        this.#age = age;
    }

    getFullName() {
        return `${this.#name} + ${this.#surname}`;
    }
}

除了类型注释之外,它与普通的JavaScript并没有什么不同。不能从外部访问成员。但TypeScript中私有字段的真正问题在于它们在底层使用了WeakMap。

要编译这段代码,我们需要调整tsconfig.json 中的目标编译版本,必须至少是ECMAScript 2015:

代码语言:javascript
复制
{
  "compilerOptions": {
    "target": "es2015",
    "strict": true,
    "lib": ["dom","es2015"]
  }
}

这可能是一个取决于目标浏览器的问题,除非您打算为WeakMap提供一个腻子,如果仅仅是为了编写华丽的新语法,在这一点上就会产生太多的工作。

在JavaScript中总是存在这种紧张,您确实想使用新的语法,但另一方面,又不想让大量的腻子脚本让用户体验失望。

另一方面,我认为您不应该过多地担心私有类字段,即使您想要发布到更新的浏览器。至少现在是这样。对私有字段的支持几乎不存在。甚至Firefox也没有实施这个提议。

让我们看看未来会发生什么。

结论

在我写这篇文章的时候,JavaScript类字段仍然是一个提议,它很有趣,但是浏览器供应商的支持很差。你对这个功能有什么看法?

这是我的:

  • 我喜欢ES私有类字段(尽管我不喜欢#)
  • 我会一直等到私有类字段出现在所有主流浏览器中
  • 因为弱映射,我今天不会在TS中使用私有类字段
  • private在TypeScript中似乎是一个更好的选择,但只能在静态级别上工作
  • TypeScript 3.8私有字段的官方声明。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JavaScript私有类字段和隐私的需要
  • JavaScript私有类字段,一个例子
  • TypeScript中的私有修饰符
  • TypeScript中的私有类字段
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档