In javascript, if i'm not using a class, i can do something like this:
const Module = (function(){
const myArray = [];
const myObject = {};
return { //this is my interfaces
myArray,
myObject,
myMethod1,
myMethod2,
myMethod3,
myMethod4,
myMethod99,
}
function myMethod1(){}
function myMethod2(){}
function myMethod3(){}
function myMethod4(){}
function myMethod99(){}
})
This provides me with some kind of structuring that let me list all the publicly available properties and methods on top so it's easier to navigate between module and see what are the available things in a module, and also it's easier to navigate to the function when using Intellisense from IDE such as Visual Studio Code, just go to the module, click the method you want to go to, then press F12, it will bring you to the function.
Now different case with class in javascript:
class Module{
constructor(){}
myMethod1(){}
myMethod2(){}
myMethod3(){}
myMethod4(){}
myMethod99(){}
}
in this case i can't separate the interface and implementation making it hard to navigate through the code. Is there any possibility that the Javascript can handle this kind of case?
There are no private members in JavaScript, yet. There exists a proposal which includes this feature, and while it is at Stage 3, it has not yet landed.
There are also no interfaces in JavaScript, (since there's barely even a type-system) and it's unlikely that one will be added in the future.
Consider using TypeScript, it has both of those features.
Related
so, i instantiate a new class in javascript, and then add it to a list ... Later I go through the list and instantiate all the classes again, to work with them.
the Javascript:
var BPmanager = Java.type('paperVS.tabs.blueprint.BlueprintManager');
var abstractFunction= Java.extend(Java.type('paperVS.logic.function.Function'));
var getYPos = new abstractFunction("getYPos") {
//Some Functions
}
BPmanager.allFunctions.add(getYPos);
and later in Java:
for (Function fun : allFunctions) {
try {
Class<?> c = Class.forName(fun.getClass().getName());
Object object = c.newInstance();
instances.add((Function)object);
} catch (Exception e) {
e.printStackTrace();
}
}
Exeption:
java.lang.ClassNotFoundException: jdk.nashorn.javaadapters.paperVS_logic_function_Function
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at paperVS.tabs.blueprint.BlueprintManager.getFromList(BlueprintManager.java:176)
This code works for all classes except the Javascript classes.
The Javascript works fine (loading and executing the single instance), but not instancing of the Class. The normal ClassLoader does the same
Java ClassLoaders use a delegation model, where the system instantiates a "primordial" (or "system") class loader, and then class loaders can be created that look in specialized places for classes, and if not found, look in the ancestor (or delegate) class loader.
Nashorn has its own internal class loaders to deal with script classes; see Java 8 ScriptEngine across ClassLoaders. So you are creating classes in those class loaders, and then trying to use them in an ancestor class loader (you can see that in the stack trace) by name.
So that's one problem to solve.
Another is that these types created by Java.extend are Nashorn-managed objects, bound to a particular Nashorn script context, and will be inconvenient to use from other Java code (see comments below, where the OP notes that the classes can't be used easily, even if they're accessible).
If you want to use the JavaScript-created objects in Java code, you'll want to create Java objects and then pass them back to Java. You seem to be doing this, so perhaps you're just using them incorrectly. Making guesses based on your class names, etc., I am guessing that rather than:
Class<?> c = Class.forName(fun.getClass().getName());
Object object = c.newInstance();
instances.add((Function)object);
... you may just want something like:
instances.add((Function)fun);
What I would like to do is load javascript to create a library of methods in an object and wait until the object is used for the first time before it is actually defined or compiled. I would like to build references to this object before it is actually fully defined. When I call a method on this object for the first time before the methods on the object are ever defined (meaning the object doesn't actually have methods) I would like to define the object and then call the method. Is there a way to do this using standard syntax such as "MyLibrary.sayHello()" if "sayHello()" is not yet defined on the object.
I imagine it would look like this:
var independentVar = "noCommitments";
var MyLibrary = function(user_ini){
//MyLibrary.init looks like
// (function(ini){
// var a = ini;
// return function(){
// //Notice the method sayHello defines when called,
// // and does not return a reference
// return {
// b:a,c:"c",sayHello:function(z){return "Hello"+a+z}
// }
// }
// })(user_ini);
var d1 = myRequire("MyLibrary.init");
return {
**handleAll : function(){ this = d1(); this.("**calledMethod")}
}
};
var greeting = MyLibrary.sayHello();
alert(greeting);
This is only pseudo-code. If I add a method to cleanup I can then return that object to the uninitialized state of "{**handleAll:function(){/noContext/}}". My application/library has a stub and a link this way and can be used immediately from an undefined state, when building modules this can be useful in order to lower the number of references to a utility, say a post has a menu of functions and those functions are shared by by all posts, -- with a mechanism such as is described here only the "active post"/"post in focus" will reference the utility. It moreless give the ability to activate and de-activate modules. The special part is the modules are already warmed up, they are ready to call functions even though they do not reference them yet, it is similar to live binding but allows the whole user interface to already be defined with functions already stubbed out with the exact name they will have when they are usable. A control mechanism for defaults and debounce is easily found in this model for me.
My question is: Is this type of scripting possible natively or will I have to use some form of compilation like for TypeScript, CoffeeScript or others. I understand it is possible if I pass the method I would like to call as a parameter to a singleton factory. I ultimately would like whole applications that are able to gracefully degrade unused functionality without polluting the code.
What I mean by pollution:
var LibDef = (
function(){
return {
callUndefined:function(methodName){
var returnVal = {}
}
}
})()
var MySingltonLibrary = moduleSinglton.getLibrary("MyLibrary", Lib);
var greeting = MySingltonLibrary.callUndefined("sayHello");
//
// Please use your imagination to consider the complexity in the singlton
The best way that will allow you to tear down an object releasing any space its functions and members consume on the heap and maintain a single reference, that will allow the object to rebuild itself or just rebuild the function that is called is like this - (A very simple model, you may like to use arrays and gradually tear down nested objects internally):
var twentySecondObj(function(window,document){
var base_obj = undefined;
var externalAPI = undefined;
setTimeout(function(){
base_obj = undefined;
},20000);
return function(){
base_obj = (function(base_obj){
if(base_obj === undefined){
return {
property1:"This is property1",
property2:"This is property2"
}
}
})();
externalAPI = (function(){
if(externalAPI === undefined){
return {
property1:base_obj.property1,
property2:base_obj.property2
}
}
})();
return externalAPI;
}
})(window,document);
console.log(twentySecondObj().property1);
On an additional note, you can use getters and setters to observe access to properties and can internally present a facade of both functions and properties which reference a build method like the one above, this way it looks like you are accessing a legit member of the object. There are no options I can think of that will allow you to intercept when attempt to set a new property on an object like: myObj.fooProperty = "foo", and buildup that property into a custom object with a getter and setter, if you have a custom type that needs to be set, then you will have to know it's implimentation details to set it, or call a function passing in the property name and value, or use a method similar to what is shown above.
Here is a link to the proposal for adding weak references to javascript: https://ponyfoo.com/articles/weakref weak-references would alter how this looks, however would not address everything mentioned in this question. Remapping an object when a property is added via some type of deep observer will allow new property members to be enhanced at the time they are set, this would require that the observer ran synchrounously when the property was set, or once the set is complete, the very next statement must be a call to update the object. I will keep posted here for any advances I see that will make the "default handler function" available within javascript in the future.
WeakRef can absolutely be used for recording and handling object usage. I would really like to move object management into webworkers and service workers so they can be maintained through all web endpoints on the domain and do not require to reload across requests. Web frameworks would need to have modified handle to offload all dom changes and updates to worker, essentially a single hook that handles message passing for all hooks. Modload, now must include a message handle name and have task priority meta data so it is properly placed in the least busy or least active worker (slow worker and fast worker) this helps to create an api that can offload to cloud functions, this shpuld give us ability to do more AI, lookups and work offline that is currently handled for most apps in the cloud where more processing power is, and in this way we can gracefully augment local processing with cloud functions only when local resources, or completion times are degraded below acceptable speeds, or above acceptable power policy.
https://v8.dev/features/weak-references
Around one year ago we started a web system that over the time has grown quite a bit. From the beginning the goal was to build reusable code that would speed up the development of future projects, and it has. With every new project, the reusable code from the previous was taken and build upon it.
At the moment, the server side code is really clean, and there is a clear separation between the "framework" (generic functionality) and the project specific logic.
However, the javascript has grown out of control. For the page specific javascript (button events, ajax calls, etc.) we've been using closures and the module pattern. But the javascript common files (the ones we import in every page), are full of functions with no association between them beyond some similarities on the names.
Because of this I'm now trying to build a sort of framework (easily reusable and maintainable code) encapsulating the logic and functions we already have. It should be one "core" object and several optional "extensions". They would be in separate files to improve the order of the code. Specifically, I'm trying to achieve the following:
Encapsulation of the code to prevent name collisions. We are very comfortable with the private/public separation of the closures.
Extendable functionality, something like the open/close principle. The tricky part here is that an extension might want to access a private method of the core.
I've been reading a lot on OO in javascript, and I've even tried to understand how jQuery does it, but I'm still unable to get my head around it. For the architectural side, it seems that I should be building a module or service framework, but the ones I've found are much more complex than what I want to achieve.
If it weren't for the tricky part mentioned earlier, a simple $.extension() would do, but I'm stuck in the how to access a core private method from an extension part. In short, my question would be: Is there a recommended architecture in javascript to build something like the following example?
var framework = function () {
//Private variable
var internalState = 1;
//Private method
var validState = function () { ... }
//Public methods
return {
commonTask1: function () { ... },
commonTask2: function () { ... }
}
}();
framework.addMoreFunctionality(function () {
var specificData = '';
return {
extensionMethod: function () {
//TRICKY PART HERE
if (core.validState()) { ... }
}
}
}());
Just return a function from the framework module.
return {
isValidState: function() { ... }
commonTask1: function () { ... },
commonTask2: function () { ... }
}
The isValidState function could then check the internal state.
// isValidState
function() {
if (validState()) {
return true;
}
return false;
}
Check if the state is valid then by calling core.isValidState(); Like this you will not get any reference to any "private" variable inside the framework core because the functions returns a bool and not a direct reference to any objects.
Have you explored DOJO ? It has module system, a build system and very elaborate OO framework implemented.
You can have your own modules / "base Dijits" that will help you implement "generic modules/widgets" and then extend them per-project, by writing / adding specific capabilities the way you have described.
DOJO is not exactly in Vogue, but if your application deals with forms like interface, then it's definitely a candidate.
For performance optimization I'm using a single JavaScript file to handle all the pages of the website I'm working on.
The basic structure I'm using is as followed:
(function($) {
// Shared functions ...
// A function for every page
function Page1() {
}
Page1.prototype = {
init: function() {
//...
},
//more functions
};
// more pages
$(document).ready(function() {
if ($('#page1uniqueidentifier').length) {
var page1 = new Page1();
page1.init();
}
// more pages
}
}) (jQuery);
I'm not an experienced JavaScript programmer so I've been searching a lot about best practices and different ways of structuring my code and I've ended up choosing this one but I'm not really sure about it and I have a few questions:
Is it worth it to use prototype if I'm never gonna have more than a single instance of a page? I think I understand how prototype works and that I'm not gaining any performance there. But I'm using it just as a best practice because in the case different instances would exist, these functions would be the same in every instance.
Is there a better way to structure the code?
Should I put the call of the init function inside the constructor and then only call new Page1()?
function Page1() {
this.init();
}
if ($('#page1uniqueidentifier').length) {
new Page1();
}
For performance optimization I'm using a single JavaScript file to
handle all the pages of the website I'm working on
That makes no sense. You should separate code into files, and then run all your js files thru a minimizer/concatenator to package it up.
Anyway, to answer your questions,
if you are only going to have 1, then prototype won't buy you anything. However, if you are going to use more than 1, would you go back and change it? Plus, using prototype wont hurt you either, so you might as well do it for learning.
You should create the files that make sense according to the functionality implemented. I would separate your object definition into its own file, for example, so when you look at that file, all you see is the code for that object.
If you have a constructor function, you don't really need init, do you?
Is anyone able to help illustrate Dependency inversion principle in JavaScript jQuery?
Which would highlight and explain these 2 points:
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
What are abstractions or high/low level modules?
This will really help in my understanding, thanks!
I would say the DIP applies in JavaScript much the same way as it applies in most programming languages, but you have to be aware of the role of duck typing. Let's do an example to see what I mean...
Let's say I want to contact the server for some data. Without applying DIP, this might look like:
$.get("/address/to/data", function (data) {
$("#thingy1").text(data.property1);
$("#thingy2").text(data.property2);
});
With DIP, I might instead write code like
fillFromServer("/address/to/data", thingyView);
where the abstraction fillFromServer can for the particular case where we want to use jQuery's Ajax be implemented as
function fillFromServer(url, view) {
$.get(url, function (data) {
view.setValues(data);
});
}
and the abstraction view can be implemented for the particular case of a view based on elements with IDs thingy1 and thingy2 as
var thingyView = {
setValues: function (data) {
$("#thingy1").text(data.property1);
$("#thingy2").text(data.property2);
}
};
Principle A:
fillFromServer belongs in a low-level module, handling as it does the low-level interaction between the server and the view. Something like, say, a settingsUpdater object would be part of a higher-level module, and it would rely on the fillFromServer abstraction---not on the details of it, which are in this case implemented via jQuery.
Similarly, fillFromServer does not depend on specifics of the DOM elements and their IDs to perform its work; instead, it depends on the abstraction of a view, which for its purposes is any type that has a setValues method. (This is what is meant by "duck typing.")
Principle B:
This is a bit less easy to see in JavaScript, with its duck-typing; in particular, something like view does not derive from (i.e. depend on) some kind of viewInterface type. But we can say that our particular instance, the thingyView, is a detail that "depends" on the abstraction view.
Realistically, it is "depending" on the fact that callers understand what kind of methods should be called, i.e. that callers are aware of the appropriate abstraction. In the usual object-oriented languages, it is easier to see the dependency of thingyView explicitly on the abstraction itself. In such languages, the abstraction would be embodied in an interface (say, IView in C# or Viewable in Java), and the explicit dependency is via inheritance (class ThingyView : IView or class ThingyView implements Viewable). The same sentiment applies, however.
Why is this cool? Well, let's say one day I needed to put the server data into textboxes with IDs text1 and text2 instead of <span />s with IDs thingy1 and thingy2. Furthermore, let's say that this code was being called very very often, and benchmarking revealed that critical performance was being lost via the use of jQuery. I could then just create a new "implementation" of the view abstraction, like so:
var textViewNoJQuery = {
setValues: function (data) {
document.getElementById("text1").value = data.property1;
document.getElementById("text2").value = data.property2;
}
};
Then I inject this particular instance of the view abstraction into my fillFromServer abstraction:
fillFromServer("/address/to/data", textViewNoJQuery);
This required no changes to fillFromServer code, because it depended only on the abstraction of a view with a setValues method, and not on the details of the DOM and how we access it. Not only is this satisfying in that we can reuse code, it also indicates that we have cleanly separated our concerns and created very future-proof code.
EDIT:
This shows the usage of DIP in raw JavaScript and a less-complete jQuery example. However, the following description can be easily applied to jQuery. See jQuery example at the bottom.
The best way is to take advantage of the "Adapter Pattern" -- also called a "wrapper".
An Adapter is basically a way of wrapping an object or module in such a way that it provides the same consistent interface to its dependents. That way, the dependent class (usually a higher-level class) can easily swap out modules of the same type.
An example of this would be a high-level (or supra) module whom depends on Geo/Mapping modules.
Lets analyze this. If our supra module is already using GoogleMaps but then management decides its cheaper to go with LeafletMaps -- we don't want to have to rewrite every method call from gMap.showMap(user, latLong) to leaflet.render(apiSecret,latLong, user), et al. This would be a nightmare to have to port our application from one framework to an other this way.
What we want: We would like a "wrapper" that provides the same consistant interface to the supra module -- and do this for every lower-level module (or infra module).
Here is a vary simple example:
var infra1 = (function(){
function alertMessage(message){
alert(message);
}
return {
notify: alertMessage
};
})();
var infra2 = (function(){
function logMessage(message){
console.log(message);
}
return {
notify: logMessage
};
})();
var Supra = function(writer){
var notifier = writer;
function writeMessage(msg){
notifier.notify(msg);
}
this.writeNotification = writeMessage;
};
var supra;
supra = new Supra(infra1);
supra.writeNotification('This is a message');
supra = new Supra(infra2);
supra.writeNotification('This is a message');
Notice that no matter which type of lower-level module "write" we use (in this case infra1 and infra2), we do not have to rewrite any of the implementation of our high-level module, Supra. This is because DIP takes advantage of two different Software Design Principles: "IoC" (Inversion of Control) and "DI" (Dependency Injection).
The best analogy that I've come across is the picture shown below.
Every electrical source relies on an interface specific for the types of things that need to plug into it.
jQuery Description:
This pattern can be easily applied to the usage of frameworks such as jQuery. One example would be the simple DOM-Query handle. We can use DIP to allow loose-coupling so that if we ever decide to switch frameworks or rely on native DOM-Query methods, maintenance is easy:
var jQ = (function($){
return {
getElement: $
};
})(jQuery);
var nativeModule = (function(){
return {
getElement: document.querySelector
};
})();
var SupraDOMQuery = function(api){
var helper = api, thus = this;
function queryDOM(selector){
el = helper.getElement(selector);
return thus;
}
this.get = queryDOM;
};
var DOM;
DOM = new SupraDOMQuery(jQ);
DOM.get('#id.class');
DOM = new SupraDOMQuery(nativeModule);
DOM.get('#id.class');
Obviously, this example would need magnitudes of more functionality in order to be practical, but I hope it gets the point across.
Basically, the differences between an Adapter and a Facade become somewhat trivial. In a Facade, you're looking at probably a single module that wraps an API or another module; whereas an Adapter creates a consistent Facade API for each of its modules, and exploits this technique to obviate tight-coupling.
Most of the JavaScript Design Patterns books go over the Adapter Pattern; one that specifically goes over a 'jQuery Adapter' is Learning JavaScript Design Patterns by Addy Osmani published by O'Reilly -- here. However, I also advise looking into Pro JavaScript Design Patterns by Dustin Diaz and Ross Harmes published by Apress -- check it out. Nevertheless, I think its important to understand the context in which we plan to implement DIP in relation to jQuery.
I hope this helps to clarify things :)
Here's my understanding and would appreciate feedback. The key test is 'who has the power'.
In a traditional implementation
High Level (HL) Code --> Low Level (LL) Code.
So for example
LL code
function LLdoAlert(text) { alert(message); }
function LLdoConsole(text) { console.log(message); }
HL Code
LLdoAlert('Hi there');
LLdoConsole('Hi there');
Here the LL code has the power. Change the LL function name for example, HL code breaks.
With dependency inversion
High Level (HL) Code --> HL/LL service interface <-- Low Level (LL) Code.
Where the HL code also owns the service interface. So for example
HL Code
var HLdoOutputSI = {
exec: function(method, text) {
if (this[method]) this[method](text);
},
register: function(name, fn) {
this[name] = fn;
}
}
HLdoOutputSI.exec('alert', 'Hi there');
HLdoOutputSI.exec('console', 'Hi there');
LL code:
HLdoOutputSI.register('alert', function(text) { alert(message); });
HLdoOutputSI.register('console', function(text) { console.log(message); }
Here we can now have any number of LL code items registering functions, but none break the HL code. (If none register, functionality is skipped). If LL code want's to play, they have to follow the HL code method. I.e. power now shifted from LL to HL.
Dependency inversion principle in JavaScript jQuery
There's no any connection between DI and jQuery. DI is all about the structure and assembling application from compoents. jQuery is a handy wrapper around DOM, nothing more, it has no any structure or components.
You can use DI to assembly Your JavaScript Application, but it would looks much the same no matter do You use jQuery or not.