TypeScript 中的私有属性

我们知道,TypeScript 是无法直接运行在浏览器中的,也无法直接运行在 nodejs 中。必须先编译成 js 以后才能运行在这些环境中。

当然这也不是绝对的,去年 nodejs 之父又新开了个坑——deno,能够直接运行 TypeScript。

之前因为觉得反正 TypeScript 最终是会编译成 js 运行在浏览器中或者 nodejs 环境中,那么是否 TypeScript 中所有的特性,都能在 js 中找到对应的书写方式呢?

之前看一些 TypeScript 中类型的实现,感觉蛮有意思的,特别是对比 TypeScript 源码和编译后的 js 代码:

比如 typeScript 中的枚举:

enum Color {
    Red = 1,
    Green,
    Blue
}
let c: Color = Color.Green;

编译以后的 js 代码:

var Color;
(function (Color) {
    Color[Color["Red"] = 1] = "Red";
    Color[Color["Green"] = 2] = "Green";
    Color[Color["Blue"] = 3] = "Blue";
})(Color || (Color = {}));
var c = Color.Green;

比如以前从没觉得,原来 js 可以这么玩,创建一个对象,对象里面的 key、value 可以互相映射,通过 key 可以找到 value,通过 value 也可以找到 key。当然这里面,你得把 key、value 理解成一类数据的代称,比如例子中得颜色和数值。

而且,从这个编译以后得 js 代码中,我学到了一个很有意思的技巧,原来对于对象的属性进行赋值的时候,执行完赋值语句以后,是有返回值的。

不过结合对象的 get\set 属性想想,就应该知道这个道理并不难理解了。

赋值,同样是调用了一个方法,最后给个返回值,这个返回值刚好是就是传入的值,以显示赋值成功,这个设计理念很好理解,也很符合逻辑。

当这个概念用久了,我就想当然的以为,TypeScript 中的代码应该所有的都能编译成对应的 JavaScript 代码,并且也应该是符合逻辑的。

但是直到我碰见了类中的私有属性,才颠覆了我这个惯性认知。

我们知道的是,Javascript 的类中是没有私有属性的,如果想模拟私有属性的话,必须要用闭包来模拟。

比如下面这段 TypeScript 代码

class Animal {
    private name: string;
    constructor(theName: string) {
        this.name = theName;
    }
    private sayName(): string {
        return this.name;
    }
}

我本以为编译成 JavaScript 会是这样的:

var Animal = /** @class */ (function () {
    var name;
    function Animal(theName) {
        name = theName;
    }
    Animal.prototype.sayName = function () {
        return name;
    };
    return Animal;
}());

如果编译以后,代码是像我预料的这样的话,那么这个地方的私有属性也就合情合理了,毕竟我在这个类的外部是完全无法访问到这个属性的,只在定义这个类的作用域内部才能访问到。

但是实际上,我用最新的 TypeScript 3.1 版本编译上述代码以后,结果是这样的:

var Animal = /** @class */ (function () {
    function Animal(theName) {
        this.name = theName;
    }
    Animal.prototype.sayName = function () {
        return this.name;
    };
    return Animal;
}());

这个结果刚开始让我很难理解,这样定义构造函数,这个 name 怎么能算上是私有属性呢?

这个问题我纠结了很久,苦思不得其解。

知道我看到了 deno,我才想明白,其中的缘由。

我们知道,TypeScript 是 JavaScript 的超集,那么就说明,TypeScript 中的概念不一定在 JavaScript 中存在,但是反过来是肯定的。

明白了这一点,就不难理解其缘由了。

TypeScript 解决了 JavaScript 中的一些痛点,没有类型约束、浏览器支持滞后等等。但是这不意味着,TypeScript 就等同于 JavaScript 了。如果两者完全等同,何必要花费这么大力气造一个新的轮子呢?

TypeScript 编译成 JavaScript 后的代码,如果你混合着别的 JavaScript 源码来用,照样是缺乏安全性保障的。但是它安全性体现在,我们如果全部是用 TypeScript 来写我们的项目,编译器会负责把我们 TypeScript 源码编译成能正确运行的 JavaScript 代码,并且至少有 99.99% 的概率能够确保在运行期间不会出错。

这不由得让我联想到,机器码和高级编程语言之间的关系。既然所有的编程语言都需要编译成机器码才能跑在计算机上,那么为什么我们说 JavaScript 写的代码安全性太差,而 Java 写出来的代码安全性更好,更适用于大型的工程呢?

究其原因,大概就是因为,不同语言对使用者的要求是不尽相同的吧。深谙 JavaScript 的老手,写出来的代码,我不相信会比一个 Java 新手写出来的代码可靠性要差。

如果把 JavaScript 比作是一把砍刀,那么 Java 就是一把匕首。

砍刀看起来威风八面,作战半径很大,只要是个力气大的人,拿起来就敢上战场砍人。但是匕首呢,很多人拿着就很发怵了,这玩意这么短,拿着砍人不是送人头么。

砍刀虽好用,但是想用好却难,用来有效的杀敌更难;匕首虽然难习,但是一旦习成,近战肉搏,杀人效率堪称恐怖如斯。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值