admin管理员组

文章数量:1417092

I have added following class in typescript

class Person {
    private variable1;
    public varibele2;

    Person(){
        this.variable1 = 'abc';
        this.varibele2 = 'xyz'; 
    }

    public getVariable1(){
        return this.variable1;        
    }
}

So When I pile the code using tsc , it generates the following code

var Person =  (function () {
    function Person() {
    }
    Person.prototype.Person = function () {
        this.variable1 = 'abc';
        this.varibele2 = 'xyz';
    };
    Person.prototype.getVariable1 = function () {
        return this.variable1;
    };
    return Person;
}());

Since variable1 is private should not be accessible by the obj of that class(which is happening in typescript code).

Same behavior should be happened into transpiled es5 code(But not happening).

In above example's transpiled code I am creating object of the Person

var p = new Person();
console.log(p.variable1); // undefined 
p.variable1 = 'abc1';  // setting value to variable 1 
console.log(p.variable1); // 'abc1'
console.log(p.getVariable1()); // 'abc1'

In above code I should not be able to set or get the value of variable1.

var p = new Person();
console.log(p.getVariable1()); // 'undefined' 
p.variable1 = 'abc1';  // setting value to variable1 
console.log(p.getVariable1()); // 'abc1'

In above code , I am trying fetch the value using p.getVariable1() and I get undefined.Since value is already assigned in constructor of the class , it should be available through p.getVariable1()

var p = new Person();
console.log(p.variable2); // undefined
p.variable2 = 'xyz1'; // setting value
console.log(p.variable2);// 'xyz1'

In above code Variable2 should retrun 'xyz' but it's not. Once i assign value to it , it returns.

So Behavior of private and public variables are same in transpiled code and its very confusing. Its not returning the value which is assigned in constructor.

I have added following class in typescript

class Person {
    private variable1;
    public varibele2;

    Person(){
        this.variable1 = 'abc';
        this.varibele2 = 'xyz'; 
    }

    public getVariable1(){
        return this.variable1;        
    }
}

So When I pile the code using tsc , it generates the following code

var Person =  (function () {
    function Person() {
    }
    Person.prototype.Person = function () {
        this.variable1 = 'abc';
        this.varibele2 = 'xyz';
    };
    Person.prototype.getVariable1 = function () {
        return this.variable1;
    };
    return Person;
}());

Since variable1 is private should not be accessible by the obj of that class(which is happening in typescript code).

Same behavior should be happened into transpiled es5 code(But not happening).

In above example's transpiled code I am creating object of the Person

var p = new Person();
console.log(p.variable1); // undefined 
p.variable1 = 'abc1';  // setting value to variable 1 
console.log(p.variable1); // 'abc1'
console.log(p.getVariable1()); // 'abc1'

In above code I should not be able to set or get the value of variable1.

var p = new Person();
console.log(p.getVariable1()); // 'undefined' 
p.variable1 = 'abc1';  // setting value to variable1 
console.log(p.getVariable1()); // 'abc1'

In above code , I am trying fetch the value using p.getVariable1() and I get undefined.Since value is already assigned in constructor of the class , it should be available through p.getVariable1()

var p = new Person();
console.log(p.variable2); // undefined
p.variable2 = 'xyz1'; // setting value
console.log(p.variable2);// 'xyz1'

In above code Variable2 should retrun 'xyz' but it's not. Once i assign value to it , it returns.

So Behavior of private and public variables are same in transpiled code and its very confusing. Its not returning the value which is assigned in constructor.

Share Improve this question asked Sep 24, 2017 at 15:19 mihir hapaliyamihir hapaliya 2972 silver badges9 bronze badges 8
  • 8 Javascript does not have private variables. Typescript's private variables are only checked at pile time, which is useful for development, but doesn't provide protections at runtime. – Nicholas Tower Commented Sep 24, 2017 at 15:20
  • I understand that javascript doesn't provide access modifier(protection or data hiding) concept but there is a way to achieve data hiding using closure, but here piled code is not implementing proper closure for making variables public and private. – mihir hapaliya Commented Sep 24, 2017 at 16:03
  • Yes, closures can make variables private-ish, but that's not what typescript's goal is. Typescript provides pile time checking, and nothing else. – Nicholas Tower Commented Sep 24, 2017 at 16:06
  • Is there a reason that you need the checks at runtime? Is it not enough that the IDE or build process tells you there's an type error when you try to access p.variable1? – Nicholas Tower Commented Sep 24, 2017 at 16:10
  • I am thinking about what browser understand , it understand piled javascript , if piled javascript doesn't following the same concept then whats the use of making variable private and public at pile time. – mihir hapaliya Commented Sep 24, 2017 at 16:14
 |  Show 3 more ments

4 Answers 4

Reset to default 3

To continue our discussion from the ments, here's the benefit that you get from using public vs private:

The IDE will tell you immediately that you're doing something you're not supposed to do. If you ignore these errors, the code will pile to javascript and run, but the point is that you don't ignore these errors. When you write bad code like this, typescript tells you there's a problem, and then you can fix the problem. If you have a build process, you can set it up so that these typescript errors will fail the build, thus forcing you to fix the problem before deploying.

Typescript is a tool to help you write better javascript code, by catching errors earlier and easier. It is not a tool to change the way javascript works. Typescript does not provide runtime type checking, and if that's what you're after, you won't find it. If you need closures to hide variables, then create a closure yourself.

First, to respond to your main question:

Why private variable in a class is treated as public in the transpiled code.

It's true that private properties, as well as readonly properties, are transpiled into plain properties hence "public". I think it's to simplify and boost transpilation TS→JS and to favor using TypeScript everywhere, where warnings or errors are emitted when performing invalid operations on these kind of properties: accessing a private property outside the class, reassigning a readonly property...

But you give examples with very strange behaviors. They are not due to TypeScript transpilation. I notice some issues with your class Person that have led to them:

  • In ES6 and TypeScript, the class constructor is defined using the keyword constructor, not the class name. It's even more confusing because the constructor is transpiled into a function constructor named like the class, here Person.
  • There's a typo with the second property: varibele2 instead of variable2. This is why console.log(p.variable2) can't print the expected value.

Fixing these issues, the code behaves more logically.

class Person {
    constructor(private _variable1 = 'abc', public variable2 = 'xyz') { }

    public get variable1() { return this._variable1; }
}

console.log(new Person()); // → Person { v1: [Getter], v2: "xyz", _v1: "abc", __proto__... }

The transpiled code is available through the TypeScript playground.

Note: I favor another syntax:

  • Properties are declared directly in the constructor: it's more pact, it enables type inference and we can specify other initial values.
  • Private variable are named _x to ease writing a getter get x() { return this._x; }. It's also a monly used JavaScript convention to indicate that the variable is meant to be private, without a plex pattern to really have a private property.

if the transpiled code is not using closure to make it private it means I can flout the variables when using it as a javascript library because I will never know what is private what is not. So the answer is transpiling the way typescript does is incorrect and not in true spirit of usage of javascript.

In following case as per my understanding, variable2 es undefined because object p don't contain that variable.

In following code we are including variable using p.variable2 = 'xyz1' into object p. so in the third line we get the value of that variable.

var p = new Person();
console.log(p.variable2); // undefined
p.variable2 = 'xyz1'; // setting value
console.log(p.variable2);// 'xyz1'

Still the question is since typescript has declared the variable then why javascript(piled code) object doesn't contain those variables?

本文标签: javascriptWhy private variable in a class is treated as public in the transpiled codeStack Overflow