0

My code is as follow

@Component({
  selector: 'my-app',
  template: `
    <ul>
    <li *ngFor = 'let hero1 of heros2'>
    {{hero1.name}}
    </li>
    </ul>        
 `})

export class AppComponent {   
heros2 : any = [
    new heross('lee', 'lee'),
    new heross('lee1', 'lee1'),
];}

class heross{
 private name : string;
 constructor(name : string, details : string){
     this.name = name; 
}}
bootstrap(AppComponent);

why am I able to access name in the view and displaying name, provided that I have given it private keyword

Liam
  • 27,717
  • 28
  • 128
  • 190
blackHawk
  • 6,047
  • 13
  • 57
  • 100
  • Possible duplicate of [Why can I access TypeScript private members when I shouldn't be able to?](https://stackoverflow.com/questions/12713659/why-can-i-access-typescript-private-members-when-i-shouldnt-be-able-to) – Liam Feb 26 '19 at 13:09

3 Answers3

2

If you'll try:

class A {
    private x: number;
}

let a = new A();
console.log(a.x);

(code in playground)

You'll get a compilation error:

Property 'x' is private and only accessible within class 'A'

The reason you're not getting that, I suspect (as I'm not an angular developer), is that you're having hero1.name in a string so the typescript compiler doesn't treat hero1 as a variable.

I bet that if you try:

let obj = new heross("name", "details");
console.log(`heross.name: ${ obj.name }`);

Then you'll get the compilation error.
The difference being ${} instead of {{}}.

If however you're asking why that's accessible at runtime, then that's because there's no notion of visibility in javascript, it doesn't get pass the compiler.


Edit

There's a difference between the angular double curly brace ({{ }}):

The double curly brace notation {{ }} to bind expressions to elements is built-in Angular markup

Which you don't need to put into ticks, you can just use regular single/double quotes.

And the javascript template literals (${ }):

Template literals are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them. They were called "template strings" in prior editions of the ES2015 / ES6 specification

More simply:

let x = 4;
console.log(`x={{ x }}`); // outputs 'x={{ x }}'
console.log(`x=${ x }`); // outputs 'x=4'
Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
  • yes its giving error as trying to access name property in console.log but in browser console its displaying, and what about string? its accessible in double ticks of the template, it means weather its private or public if its in double ticks(for multiple strings) then its accessible – blackHawk Jun 23 '16 at 17:11
  • I updated my answer. Also, in the browser console it's only javascript, there's no typescript, and there's no such thing as private/protected in javascript. The compiler uses that information but it doesn't get translated into the compiled js. – Nitzan Tomer Jun 23 '16 at 17:25
  • What if i extend these two classes will i still be able to do the same thing – blackHawk Jun 23 '16 at 18:14
  • What same thing? Do what? I don't understand what you're talking about – Nitzan Tomer Jun 23 '16 at 21:08
1

Privacy is not enforced in TypeScript in general but only checked by static tools.

You can see the bindings in the view and the component class as a single unit, like the bindings in the template is part of the class implementation.

With the offline template compiler I assume this is actually how the generated code will be organized.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Privacy is not enforced in TypeScript in general? If so then what's the point of having the option? If I have `class A { private x: number }` then doing `new A().x` will raise `Property 'x' is private and only accessible within class 'A'` – Nitzan Tomer Jun 23 '16 at 16:46
  • As I said static analyzers (linter) warn you about accessing private fields but AFAIK currently bindings are not recognized as TypeScript code and are not included in any such checks. And for runtime privacy doesn't exist (as @AngJobs also mentioned) – Günter Zöchbauer Jun 23 '16 at 16:51
  • If by static analyzer you mean the compiler then yes. Try to compile a simple example and you'll get the error I mentioned in my previous comment. If the compiler wouldn't check that then why would the language offer this to begin with? – Nitzan Tomer Jun 23 '16 at 16:55
  • I don't know the TypeScript tools well because I use mostly Dart but I have repeatedly seen workarounds that access private members because they allow to get the desired functionality because no equivalent was available as public. I don't know what setting it depends on whether compiling fails or not when a private member is accessed. In Plunker for example this is not checked at all and the code works fine. – Günter Zöchbauer Jun 23 '16 at 17:02
  • What code? the one in the question? If so, then yes but for a different reason. If you mean my code (with `new A().x`) then I'd like to see that Plunker. You can simply workaround the privacy issue with any: `(new A() as any).x` will work just fine. – Nitzan Tomer Jun 23 '16 at 17:04
  • Right, but that files isn't being compiled at all because you don't have a `tsconfig.json` and `"use typescript";`, when I added those the preview got stuck on `loading`. If you'll try my example in playground you'll see it fails (in my answer to the question there's a link) – Nitzan Tomer Jun 23 '16 at 17:14
  • As mentioned I don't have deep TS knowledge. It somehow needs to be translated to JS in order to be executable. Is this not done by what you call "compiler" in case of my Plunker? – Günter Zöchbauer Jun 23 '16 at 17:16
  • Well, it does get compiled, but it does so with ignoring the compilation errors. I just added an inner class into your `A` class and it still worked (no inner classes in ts). Conclusion: don't use plunker for typescript. – Nitzan Tomer Jun 23 '16 at 17:30
  • But it's still working therefore if there are errors it doesn't cause the compilation to fail. Therefore the errors seem artificial. I like that I can run Dart code even when it contains errors as long as the faulty code is not actually executed. I wonder why a language like TS that is much closer to JS doesn't support that. I find that quite cumbersome. – Günter Zöchbauer Jun 23 '16 at 17:31
  • https://github.com/Microsoft/TypeScript/issues/7456: "The current design is that we still emit in the presence of type errors. Only syntax errors (i.e. invalid JavaScript - regardless of type information) cause the file not to be emitted. Note the build should still return the error, but it should also emit runnable code." – Nitzan Tomer Jun 23 '16 at 17:48
  • I see. Thanks for the explanations. – Günter Zöchbauer Jun 23 '16 at 17:49
0

Because it's javascript at the end of the day. And Javascript language does not have a private keyword.

null canvas
  • 10,201
  • 2
  • 15
  • 18