I am trying to understand decorators which are not java's annotations but more like pre-processors in this article and I also found this SO question on setting info on a function. Let's say I have an interface like so
export default interface UserService {
#Path("/users/create")
#POST
createUser(user: CreateUserRequest): Promise<CreateUserResponse>;
#Path("/users/delete")
#POST
deleteUser(user: DeleteUserRequest): Promise<DeleteUserResponse>;
}
sidenote: It would be great to use this generated client in react UI as well as use in nodejs
I want my #Path and #POST, #GET to save info I can read and I think
class Path(path:string):
def __init__(self, path):
self.path = path
def __call__(self, func):
func.pathAnnotation = self
return func
I read I cannot loop over methods in an interface yet I would like to generate the http client that implements this interface so any API developers create, it automatically creates the implementation. (In java, we use the Proxy.java to generate an implementation). On server side, the controller implements the same exact API and I like to generate the 'scaffolding' meaning the http request to which endpoint to call if possible (not sure I can do that in nodejs just yet).
EDIT: An idea: Perhaps, I create an abstract class or class and every method throws an exception "Use XXXFactory to generate the implementation of this class". How do I loop over method in that class? and can I create classes that extend all these 'apis' at runtime such that I can inject him for everyone to use(like Proxy.java in java world)?
EDIT: perhaps I could do this in javascript with a prototype class somehow... generate all the methods to call a method with signature
Promise<Object> invoke(String method, object[] paramsToMethod);
Then, I can look up the method and #Path and #GET/#POST properties on that method. Can a prototype class extend a class in javascript such that any api defined (perhaps defined in typescript) is implemented by this one class? Then I have every api implemented by the same code for every microservice like we do in java? (This then means the platform team can swap protocols and developers do not care about protocols anymore like http, http2, binary, etc)
As per request, I have took some time to tinker around with reflection. The reflection is mostly needed to make the client automatically conform to what the service expects (type of parameters/return type), and I think it might be possible with reflect-metadata.
Ok so the idea is to have decorators store metadata about the method in a map, where a key is the class and the value is a collection of the methods with metadata.
Then where you get the client, it aggregates all the metadata for each method into one function that can be used.
It's a vague start but I think it can work. I actually might also turn this into a small snippet or library too if I have the time.
But actually, this should be a statically generated client, not a dynamic one. Because then it is far easier to validate and do the code generation.
Playground
I am building an automated documentation tool for a work and I am facing some issues when searching some method references. Dynamic variables are of type "any" and their methods cannot be parsed (trying to access the definition in Visual Studio will typically result in "cannot navigate to the symbol under the caret").
More context with an example: In my source code, I am targeting every references of a "Query" method (used for AJAX calls), it is a method defined in the "Step" class. But my problem is that dynamically set variables are of type "Any" and their properties does not refer to anything: the ".Query()" method in "step.Query()" does not refere anything in particular because step is of type "any" and not "Step".
I was wondering if it is possible to enforce a type to dynamically set variables, in order to solve this issue. I know that typescript typically handle this kind of things, but if there is a way to do it in JavaScript directly that would be excellent.
I am learning design pattern in JavaScript, and I'm going to use the module pattern. I'm puzzled with two things.
1 - If I would create a plugin, then I can use the module pattern, and have private and public methods/variables. But if I have a full JavaScript file, I don't need private and public methods, since one part of the program has nothing to do with another part. So what's the point of private and public methods?
2 - Since the JavaScript file is really long, should I have nested module's? How should I go about a full file of JavaScript?
JavaScript has moved on. ES6--which there is no real reason not to move up to, if you haven't already--has its own modules. So there is no need to "simulate" modules with old patterns. Example:
// Old style.
var myModule = function() {
var privateVar;
function getPrivateVar() { return privateVar; }
return {getPrivateVar: getPrivateVar};
}();
console.log(myModule.getPrivateVar());
// New style.
let privateVar;
function getPrivateVar() { return privateVar; }
export {privateVar};
// Using it
import {getPrivateVar} from './myModule';
console.log(getPrivateVar());
In the above, privateVar is by definition private to the module (file). There's no need to keep it private by wrapping it in an IIFE. Instead of handling the exports ourselves as properties of a single returned object, we use the ES6 export mechanism to export it explicitly.
(1)
When all Javascript files are loaded, all the scripts in all files are just like they are in one file. Script in one file can access (read, update, delete) global variables in other files. There are a lot of questions on this, you can easily search for those.
Of course, "one part of the program has nothing to do with another part", but in case you are in team with many members, each works on a part of the system (or in some cases, a file). Then, there is a chance that one person accidentally changes variables created by another person. Those kinds of error are quite easy to detect. But if you can modularize you script, you can avoid those kinds of error altogether.
(2)
You can go slow. While writing code to complete requirements, try to recognize the parts of code that can be separated to a modules (or even nested modules). Them put them into other files.
You should be creative and careful while doing so. The code might grow very fast and things get out of control very quickly.
Why is there a distinction between privileged and public methods?
Why should I even bother with public methods, aren't privileged
methods more natural? They feel more intuitive as they allow access
to private methods and variables like in java.
Is there a specific reason behind this or was this an error in the
spec(got a little ahead of myself there!) or am I missing something?
In what situation would you use a public method over a privileged method?
here is the code to demonstrate:
var Foo = function(){
var privateVar = "i am private";
function privateFunc(){
console.log(privateVar);
}
this.privilegedFunc = function(){
privateFunc(); // can access
}
};
Foo.prototype.publicFunc = function(){
privateFunc(); // cannot access
};
var foo = new Foo();
foo.privilegedFunc(); // prints "i am private"
foo.publicFunc(); // Uncaught ReferenceError: privateFunc is not defined
it's just like any OOP language (without the visibility keywords though), if you need a method to be called outside the instance, public, else, private.
Functions that are not bound to this, cannot be accessed outside the scope because they are defined and declared in the scope of the constructor function.
And as per your latest comment, there are many reasons and scenarios where you will have to expose an objects function in order to be used by other objects e.g.
As per your comment in this answer, lets see some advantages of the prototype approach.
By using prototype, you are able to change a method and the change will reflect to all instances that share the same prototype, without the prototype, each instance will have it's own version of the given method, therefore you will have to change them one by one.
Another advantage, is performance, functions/methods declared in the prototype are only created once, whereas without the prototype, each time you use the new keyword to instantiate from a constructor function, all functions inside the constructor functions scope will have to be created.
It's important to note that there's no distinction in the spec between "privileged" and "public" methods (in fact I don't think the spec uses these terms at all - Douglas Crockford does), they are governed by the exact same rules, the most fundamental of which in play being function scope.
Note: I'll follow your terminology in my answer, but I actually recommend against it: more often you'll find people calling your privileged methods public, and your public methods prototype methods.
In your example, this.privilegedFunc has access to the private variable privateFunc because they are defined in the same scope - that is, the scope of the Foo constructor function. privilegedFunc will be able to use its reference to privateFunc even when called from "outside", via the so-called closure mechanism of the language.
To answer your questions directly:
Why is there a distinction between privileged and public methods?
There isn't a fundamental distinction. You defined two functions in different scopes, and as such, they can reference different variables.
Why should I even bother with public methods, aren't privileged methods more natural?
Natural is quite a subjective term. However, if you don't wish to expose fields directly, you need to use a privileged function to manipulate them from the outside.
They feel more intuitive as they allow access to private methods and variables like in java.
That intuition is based only on familiarity :) No wonder that when you try to use Javascript as Java, the parts which work differently in the two languages will seem the least intuitive. This doesn't mean that you should try to imitate the style you would use in either in the other, some solutions are better suited for Javascript, some better for Java.
Is there a specific reason behind this or was this an error in the spec or am I missing something?
(Such a fundamental error in the spec?! God no.) I'm not sure what you mean by "this", but the difference in visibility is explained by function scopes, see above.
In what situation would you use a public method over a privileged method?
For example, if you don't need to expose private fields via closures. An other noteworthy difference is that functions on the prototype will be shared (i.e. effectively the same function instance) amongst instances, while private and privileged methods will be unique to the instance, which can have an effect on memory footprint.
What you call "privileged" methods aren't part of the language syntax. Rather, it's a design pattern. It is possible due to the fact that javascript implement closures (the ability of functions to access the scope of an outer function even after that outer function has returned).
There is a theory that all languages that implement closures (or even just first-class functions) can implement an object system. Several functional languages took this approach when adding OO to the language: that OO features are not part of the language syntax but a library that you can use (or even write yourself). One of the prime examples of this is CLOS (Common Lisp Object System) in Lisp. It's a library that adds OO features to the language without needing to modify the language syntax.
As you have discovered, using a closure to access local variables does a good enough job to emulate the "feel" of private variables and public methods. This is a feature of closures - that you can create your own OO system without needing OO features.
The OO system in javascript was added because OO was a big deal then. Admittedly, if Brendan Eich didn't add OO to javascript we could have evolved a (or several) OO systems from scratch using pure javascript. Indeed, in the early 2000s people weren't comfortable with the prototypal object system in javascript and developed their own OO system to emulate what they were used to.
In javascript, the OO system has no concept of private methods or variables. This was deliberate. Several other languages share this philosophy that private members are a "mistake". The idea that privacy is bad practice was borne out of years of experience using libraries that made a feature you needed to access private. For languages that encourages open source or distribution of code that's not too big of an issue. You can always modify the library code to export what you want. But for languages that encourages distribution of libraries as compiled binaries that's a big issue. At the time javascript was created, most OO languages had features allowing you to distribute your libraries as compiled binaries. So there was a small backlash against the concept of privacy.
So.. when would you use a closure to emulate private variables? Use it when you really need something like a private variable.
Why is there a distinction between privileged and public methods?
I'm assuming you read Douglas Crockford website (this page). It's a distinction I haven't really seen used by other authors. I don't make that distinction, but I do know that the function has access to the constructor closure.
Why should I even bother with public methods, aren't privileged methods more natural? They feel more intuitive as they allow access to private methods and variables like in java.
They have a different meaning than public methods.
A) They are defined by the constructor and as such, they have access to the constructor scope. That's their privilege.
B) They aren't shared by its prototype.
A means that the function will be instantiated every time the constructor is being called. When you use the prototype, it's just linked.
B means that they are essentially different functions.
obj1.privileged !== obj2.privileged
Is there a specific reason behind this or was this an error in the spec or am I missing something?
No error from where I see it. It's just a language feature.
In what situation would you use a public method over a privileged method?
When you don't need access to any closures inside the constructor and want to take leverage of the prototype chain.
Not sure about the semantics and naming convention, but as far as patterns, here's how I'd break this down for the most cases:
privateFunc:
I'd use this type of function whenever I want to encapsulate some functionality inside a function (either when reusing this function several times, or simply because it has a logical reason to do so) that I don't want to expose as an API, usually because it doesn't make sense as an API.
publicFunc:
I'd use this type of function whenever I want to expose an API, and the implementation doesn't require any "closed" (as in closure) variables. Basically anything that uses the state of an instance of the type but needs no other resources. Also for "static" methods that are used directly from the type (same as Object.keys() for example), but this won't be declared on the prototype but rather directly on the type.
priviledgedFunc:
Same use case as publicFunc except the use of helper, "closed" variables is either required or greatly simplify implementation. There's a downside to this technique in that these methods are properties of each instance, and incur runtime penalty to construct and assign.
Why is there a distinction between privileged and public methods?
It's a consequence, not a driver, of the language's design. You will actually do fine without bothering yourself with this terminology distinction I think.
Why should I even bother with public methods, aren't privileged
methods more natural? They feel more intuitive as they allow access to
private methods and variables like in java.
Is there a specific reason behind this or was this an error in the spec > or am I missing something?
In what situation would you use a public method over a privileged method?
There are a couple of situations where you would want to bother yourself with public methods that come to mind:
Privileged methods are defined everytime an object is created while public methods are defined once at parse time. So if you are writing something that creates a bucket load of object, e.g. particle system, you may want to use public method.
You can use public methods are pure function without instantiating an object.
Your are thinking about this the wrong way. You should be thinking about scope here and not access level (public/private/protected) Javascript is not a traditional object oriented programming language.
In your example, the "privateMethod" is simply scoped to the "Foo" function, and thus cannot be accessed outside the function. Your "privilegedFunction" is attached to "this" which in javascript is the context of the "Foo" function. You can access it from an "instance" of Foo as your example shows because of scoping, and it has nothing to do with access level.
Web App Model
Suppose I have a sensitive JS object by which I can do critical stuff. My requirement is that I would like to wrap this object entirely such that no one can access it. Here is my pattern to wrap this object.
var proxy = (function (window){
// A private reference to my critical object (i.e. big apple)
var bigApple = window.bigApple;
// Delete this property so that no one else can access it
delete window.bigApple;
// Oooah, It's mine! I'm now eating it :)
// Public APIs exposed globally
return {
doStuffWithBigApple: function (){
// The Script element being executed now
var who = document.currentScript;
// Access control
if(isLegitimate(who)){
return bigApple.doStuff();
}
}
};
}) (window);
By this code I export a public literal object named proxy so that every one can access it.
What is that isLegitimate? It is an abstract function to be implemented which decides which script elements access to which methods of my big apple. The decision is made with regard to src attribute of the script element. (i.e. their domain)
Others use this public API like this:
proxy.doStuffWithBigApple();
Attack Model
In my web app there are placeholders for advertising such that external contents including JavaScript codes could be loaded and get executed. All of these external resources eagerly would want to access my big apple.
Note: Those are added after my scripts resulting in there is no access to the original window.bigApple.
My Question
Is there any circumventing way for my security model?
Critical edges:
Changing src attribute at parse-time. --- Not possible, because src can only be set once.
Adding script element at run-time --- No problem is raised
Your idea of creating a proxy is good imo, however, if you have access to ES6, why not looking into Proxy? I think it does what you want out-of-the-box.
The MDN provides good examples on how do traps for value validation in a setter, etc.
EDIT :
Possible trap I have imagined :
document.currentScript is not supported in IE. So if you care about it and decide to polyfill it/use a pre-exisiting polyfill, make sure it is secure. Or it could be used to modify on the fly the external script url returned by document.currentScript and skew the proxy. I don't know if this could happen in real life tho.
This way for protecting JavaScript objects has a very significant issue which should be addressed, otherwise this way will not work properly.
MDN noted on this API that:
It's important to note that this will not reference the <script> element if the code in the script is being called as a callback or event handler; it will only reference the element while it's initially being processed.
Thus, any call to proxy.doStuffWithBigApple(); inside callbacks and event handlers might lead to misbehaving of your framework.