Why can I access TypeScript private members when I shouldn't be able to?
Just as with the type checking, the privacy of members are only enforced within the compiler.
A private property is implemented as a regular property, and code outside the class is not allowed to access it.
To make something truly private inside the class, it can't be a member of the class, it would be a local variable created inside a function scope inside the code that creates the object. That would mean that you can't access it like a member of the class, i.e. using the this
keyword.
Why am I able to access private member of the class?
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'
Typescript private property subclass can't access
You need to change private to protected.
from typescriptlang.org:
TypeScript’s private #
TypeScript also has it’s own way to declare a member as being marked private, it cannot be accessed from outside of its containing class.
-- means private fields are going to be in all subclasses but you won't be able to access it.
Understanding protected #
The protected modifier acts much like the private modifier with the exception that members declared protected can also be accessed within deriving classes.
-- it's what you need, the fields which can't be access from outside but available in all subclasses.
Why are private members accessible through the square bracket notation?
When accessing object properties using indexes the compiler will treat the object like this:
interface BlueprintNode {
metadata: number[];
[key: string]: any;
}
If you then do:
let node: BlueprintNode;
node["metadata"].push("Access violation, rangers lead the way.");
You'll get the same error as with your code.
I can access private members in transpiled ES5 code from TypeScript
For the moment JavaScript doesn't have truly private members; the notion of private
in TypeScript is merely there to help you preventing coding mistakes. There is a possibility that in the future, ECMAScript might introduce real private members, but until then, you can still access "private members" after transpiling.
Angular2 - should private variables be accessible in the template?
UPD
Since Angular 14, it is possible to bind protected
components members in the template. This should partially address the concern of exposing internal state (which should only be accessible to the template) as the component's public API.
No, you shouldn't be using private variables in your templates.
While I like the drewmoore's answer and see perfect conceptual logic in it, implementationwise it's wrong. Templates do not exist within component classes, but outside of them. Take a look at this repo for the proof.
The only reason why it works is because TypeScript's private
keyword doesn't really make member private. Just-in-Time compilation happens in a browser at runtime and JS doesn't have any concept of private members (yet?). Credit goes to Sander Elias for putting me on the right track.
With ngc
and Ahead-of-Time compilation, you'll get errors if you try accessing private members of the component from template. Clone demonstration repo, change MyComponent
members' visibility to private and you will get compilation errors, when running ngc
. Here is also answer specific for Ahead-of-Time compilation.
Understanding public / private in typescript class
java script code that is generated is same
They produce the same JavaScript but don't have the same semantics as far as the type is concerned.
The private
member can only be accessed from inside the class whereas public
can be excessed externally.
More
The differences are covered here : https://basarat.gitbooks.io/typescript/content/docs/classes.html#access-modifiers
Another example
let foo = 123;
will generate the same ES5 as
const foo = 123;
However in the first case let foo = 123;foo = 456
will compile fine but const foo = 123; foo = 456
will result in a compile time error.
Why can I access TypeScript private members when I shouldn't be able to?
Just as with the type checking, the privacy of members are only enforced within the compiler.
A private property is implemented as a regular property, and code outside the class is not allowed to access it.
To make something truly private inside the class, it can't be a member of the class, it would be a local variable created inside a function scope inside the code that creates the object. That would mean that you can't access it like a member of the class, i.e. using the this
keyword.
Related Topics
Restart a Gif Animation Without Reloading the File
Why Does Reflow Need to Be Triggered for CSS Transitions
Get All Computed Style of an Element
Extract the Current Dom and Print It as a String, with Styles Intact
Change Svg Fill Color in :Before or :After CSS
How to Dynamically Remove a Stylesheet from the Current Page
Converting Em to Px in JavaScript (And Getting Default Font Size)
Creating a CSS Class in Jquery
Jquery-Ui Datepicker Change Z-Index
Detecting by How Much User Has Scrolled
HTML Button to Not Submit Form
How to Use Jquery with Reactjs
How to Split a Long Array into Smaller Arrays, with JavaScript
How to Access the Request Body When Posting Using Node.Js and Express