Using JsConstructor to deal with multiple constructors - javascript

I have a class with two constructors:
#JsType
public class Dog implements Animal {
String name;
public Dog() {
this.name = "Scooby Doo";
}
public Dog(String name) {
this.name = name;
}
}
I get the following error when I run gwt compile [With GWT-dev 2.8]
[ERROR] Constructor 'Dog(String)' can be a JsConstructor only if all constructors in the class are delegating to it.
I have been trying to work through this error, with not much success. I am not sure how to delegate to the other constructor.
Any help is very much appreciated!
Thanks!

Alas, JavaScript can't handle multiple constructors! You get one and only one.
There are some things you can do to pretend to have more than one - you can check the incoming data, and assign sane defaults:
#JsConstructor
public Dog(#JsOptional String name) {
if (name == null) {
name = "Scooby Doo";
}
this.name = name;
}
You have to be careful of types here if your two constructors do not use the same types in the same position - judicious use of instanceof might work (just be aware that for JS objects you are using JS instanceof, not java!). Another option lets you be more flexible, but again, no overloaded methods - factory methods:
public static Dog withName(String name) {
return new Dog(name);
}
public static Doc defaultImpl() {
return new Dog();
}
#JsIgnore
public Dog() {/*...*/}
#JsIgnore
public Dog(String name) {/*...*/}
Another idea on the same theme would be to create a JsType builder. This is a bit less idiomatic for JS.
Finally, you could consider the dreaded "options object", where your one constructor takes a single Object with properties, or a JsPropertyMap<Any> holding all the possible values, then check nullness and types inside the giant constructor. I avoid this personally - this is one of the terrible things I'm hoping to avoid by writing Java in the first place.

Related

How to protect functions which are called with different contexts from breaking?

I'm fairly new to javascript and now I learned how calling functions with a context works.
Here is a simple example that poses a question in my head. Lets say we have this example:
var myObj = {
bar: function() {
console.log("Lets got to the bar!");
}
}
/* how can this be protected from errors,
* if a passed object doesn't contain bar */
function foo()
{
this.bar();
}
foo.call(myObj);
Now, how can foo be protected of breaking? In some OOP language (lets say Java) this would be implemented lets say via an interface. So in that case if the object being instantiated hasn't implemented the interface method, the compiler would through an error so the compiler protects the code/program from being faulty (in this case of course).
public interface MyInterface
{
public void bar();
}
public class MyClass implements MyInterface
{
public void bar()
{
System.println("Lets go to the bar");
}
}
MyInterface m = new MyClass();
m.bar(); // if bar isn't implemented the compiler would warn/break
Note: I'm not that good in Java so sorry for any syntax or other errors, but I hope you get the point.
So to sum up, as I see that in both cases in both languages one can achieve polymorphism, right? Now if so for the Javascript example, how can one protect it from breaking, are there any patterns or tricks? Does typeof this.bar === function work? If so, who guarantees the SW quality if the programmer forgets this, I'm asking this kind of question because Java has the compiler to warn the programmer about the mistake, does JS have something similar, some quality check tool?
Javascript is a dynamic interpeted* language. There isn't a compiler step to check references. Some tools (jsline) and IDEs (VS, Webstorm) can perform some design-time checks for you, but there's no true type safety. This is largely seen as a feature, not a bug.
There's an array of tricks to work around this (.hasOwnProperty, typeof x === 'function', storing self references, context binding) but mostly, if you want a type safety, you want a different language.
My recommendation is Typescript. It has a Java/C-like syntax, with some familiar OOP features, like classes, interface (and thus, sane polymorphism) and generic types, and transpiles to javascript in moments.
If you use a constructor to create your object you can use Javascript's builtin class member ship checking features. An example is below.
class MyClass {
bar() { console.log("Lets got to the bar!")}
}
function foo() {
if ( this instanceof MyClass ) {
this.bar();
}
else {
console.log('this is not a member of the MyClass');
}
}
foo.call(new MyClass);
Be warned that Javascript's type checking is horribly unreliable and you probably should not use it. If your object contains the same prototype anywhere in it's prototype chain as the class you are testing it for membership in, instanceof will return true.
Quick and dirty duck typing example
This will throw if you give it an object without the properties you are checking for, but you get the idea.
class MyClass {
constructor() {
this.feathers = 'white';
this.feet = 'webbed';
}
bar() { console.log("Lets got to the bar!")}
}
function foo() {
if (
this.hasOwnProperty('feathers') &&
this.hasOwnProperty('feet') &&
this.feathers === 'white' &&
this.feet === 'webbed'
)
{
this.bar();
}
else {
console.log('this is not a member of the MyClass');
}
}
foo.call(new MyClass);

Generics in Typescript - Undefined T

Having a problem with Typescript's Generics where the type is undefined in the scope of the generic function or class. I can't find any documentation on this though I would assume it is by design. Is there a way to achieve what I am trying to, type-safely?
function test<T>() {
return new T();
}
class TestClass<T> {
public build(): T {
return new T();
}
}
Link to Play:
http://www.typescriptlang.org/Playground/#src=function%20test%3CT%3E()%20%7B%0A%09return%20new%20T()%3B%0A%7D%0A%0Aclass%20TestClass%3CT%3E%20%7B%0A%09public%20build()%3A%20T%20%7B%0A%09%09return%20new%20T()%3B%0A%09%7D%0A%7D%0A
TypeScript generics (unlike other languages like C#) are compile time only. So you cannot use them in runtime positions e.g. new T.
Is there a way to achieve what I am trying to, type-safely
Pass the constructor explicitly. e.g.
class TestClass<T> {
public build(x:{new ():T}): T {
return new x();
}
}
Here x:{new ():T} I am saying that x is something that when called with new gives an instance of T.

Javascript lack of Interface - simple solution with Prototype

In Javascript, in contrast to other languages which OOP like Java, do not provide interfaces. There is some solutions on the internet which are more complex than mine, but I want to share with you my way how to resolve this problem, to get some constructive critisism from you and check if I choose the right way of thinking. I choose Answer your own question – share your knowledge, Q&A-style and you will see my answer below.
Here is an example that uses a timeout to check if the needed functions are implemented, you can implement multiple Interfaces.
Since JS is not a compile time type checked language you can't really have a good solution for this. Maybe you can have a look at mix ins (under mix ins), leave the default implementation or override.
function PersonInterface(proto,fnName){
//after running the implements function it depends how quickly you're
// creating instances and how quickly you implement the functions
setTimeout(function(){
if(typeof proto.getSurName !== 'function'){
throw new Error(fnName + ' has to implement getSurName');
}
//and others if needed
},100);
}
function implements(fn, implements,fnName){
implements(fn.prototype,fnName);
}
function Employer(){};
implements(Employer, PersonInterface,'Employer');
//depends how quickly you set the getSurName
// and how quickly you will be creating Emplyer instances
// trying to call getSurName
// comment out the next line and you'll get
// Employer has to implement getSurName
Employer.prototype.getSurName=function(){};
My solution based on Javascript Prototype. I create a class which acts like interface by throwing Error object in methods which should be implemented, when child inherits from interface. Let's create PersonInterface:
function PersonInterface(){
}
PersonInterface.prototype.getName = function(){
throw typeof(Error) !== 'undefined'?
new Error(" Interface Person: method getName() unimplemented!")
: " Interface Person: method getName() unimplemented!";
};
PersonInterface.prototype.getSurname = function(){
throw typeof(Error) !== 'undefined'?
new Error(" Interface Person: method getSurname() unimplemented!")
: " Interface Person: method getSurname() unimplemented!";
};
Then let's create a Customer, which implements PersonInterface interface:
function Customer(name, surname){
PersonInterface.call(this);
this.__name = name;
this.__surname = surname;
}
Customer.prototype = Object.create(PersonInterface.prototype);
Customer.prototype.getName = function(){
return this.__name;
};
Customer.prototype.getSurname = function(){
return this.__surname;
};
When getName() or getSurname() function are not implemented, it throws an Error object with corresponding message. I create a JSFiddle which demonstrates how it works: Javascript Interface with Prototype (click)
When you, for example, remove getSurname() method from Customer's prototype, it throws an Error - which you find in your browser console. I know that is simple solution and on the net we can find many solutions, but I think it can resolve problem when we don't need something more complex than simple interface.

How to build an API with QJSEngine?

I am starting with Qt and one of my projects is using QJSEngine to evaluate javascript and I want to provide an entire API to the script, with classes and global functions.
Right now my program provides only the ECMAScript default stuff (eval, encodeURI, parseInt, etc...), but I need to expose some custom classes to the code, like the browsers API (WebSocket class, Image class, document object). For example:
var obj = new CustomClass("", 0);
var ret = obj.customClassMethod("[...]!");
customFunction(ret);
I need to define the behavior of the classes in C++, it wouldn't help evaluate the classes definition and let the user code run.
In contrast to QScriptEngine, where you can add custom classes if they inherit from QObject by using the Q_SCRIPT_DECLARE_QMETAOBJECT macro, the QJSEngine does not directly provide this functionality.
You can still use the Qt Meta-object system to provide interfaces for Javascript, but you have to instantiate the object in C++ and add it to the Javascript context.
Then its slots, methods defined with Q_INVOKABLE, and properties defined with Q_PROPERTY are all accessible from within the Javascript runtime.
Now you can create a factory which creates instances of your custom class CustomClass for a given QJSEngine wrapped as Javascript objects:
class CustomClassFactory : public QObject
{
Q_OBJECT
public:
CustomClassFactory(QJSEngine* engine) : m_engine(engine) {}
Q_INVOKABLE QJSValue createInstance() {
// The engine takes ownership and destroys the object if no longer required.
return m_engine->newQObject(new CustomClass());
}
private:
QJSEngine* m_engine;
}
A factory instance needs to be constructed and added to the global object of the Javascript runtime:
QJSEngine engine;
QJSValue factoryObj = engine.newQObject(new CustomClassFactory());
engine.globalObject().setProperty("_customClassFactory", factoryObj);
Now we can construct objects in Javascript with:
var obj = _customClassFactory.createInstance()
As we've come this far, lets additionally inject a constructor for the custom class into the Javascript runtime:
QJSEngine engine;
// Again, the QJSEngine will take ownership of the created object.
QJSValue factoryObj = engine.newQObject(new CustomClassFactory());
engine.globalObject().setProperty("_customClassFactory", factoryObj);
engine.evaluate(
"function CustomClass() {"
" return _customClassFactory.createInstance()"
"}");
Et voilà, now you can construct C++ object in Javascript, like you would custom Javascript classes:
var obj = new CustomClass()
For the mentioned WebSocket API you could wrap QtWebSocket for that purpose – that was exactly what I required when I came up with the proposed approach.
Note that for the sake of simplicity I omitted parameters for the constructor, but they can simply be added as well.
PS: I would have added more links to the official documentation, but due to the lack of reputation I'm not allowed to.
In Qt 5.8 a new feature was added to QJSEngine: newQMetaObject
You simple add the static meta object e.g. &MyQObjectDerivedClass::staticMetaObject to the JSEngine using the above function.
You will then be able to new those objects in Javascript from within QML. I have found this a very neat solution.
As the documentation says you must mark you constructor Q_INVOKABLE or you won't be able to instantiate an object of your class.
The property system (setters/getters) works as expected as do slots.
https://doc.qt.io/qt-5/qjsengine.html#newQMetaObject
Here is my test code - first is the C++ part that adds the meta object
QQmlApplicationEngine engine;
QJSValue jsMetaObject = engine.newQMetaObject(&MyClassOfObject::staticMetaObject);
engine.globalObject().setProperty("MyClassOfObject", jsMetaObject);
I can now write JS that news an object of that type and use setters/getters etc. This code actually exists in a MouseArea onClicked handler for manual testing.
var bob = new MyClassOfObject();
print(bob.x);
bob.x = 918264;
print(bob.x);
print(bob.words);
And here is the class definition...
class MyClassOfObject : public QObject
{
Q_OBJECT
Q_PROPERTY(int x READ getX WRITE setX)
Q_PROPERTY(int y READ getY WRITE setX)
Q_PROPERTY(QStringList words READ getWords)
public:
Q_INVOKABLE explicit MyClassOfObject(QObject *parent = nullptr);
public slots:
int getX() const { return x; }
int getY() const { return y; }
void setX(int x) { this->x = x; }
void setY(int y) { this->y = y; }
QStringList getWords() const;
private:
int x = -113;
int y = 616;
QStringList stringList;
};
As of Qt5.5 QScriptEngine has been deprecated, so only QJsEngine should be used in the future.
https://wiki.qt.io/New_Features_in_Qt_5.5#Deprecated_Functionality
If you look up Documentation of QScriptEngine, or by searching "QScriptEngine examples" you can find some stuff about making Custom C++ Classes available to QScriptEngine.
Here is a good place to start:
link to example
QScriptEngine is very similiar to QJsEngine, so it shouldn't be a big problem for you.
Hope this helps :)

How do I mimic access modifiers in JavaScript with the Prototype library?

I've been working with the prototype library for some time now and occasionally find myself wishing I had multiple access levels (public, private, and protected). The closest I've come so far is the following:
SampleBase = Class.create({
/* virtual public constructor */
initialize: function(arg1, arg2)
{
// private variables
var privateVar1, privateVar2;
// private methods
var privateMethod1 = function() { }
function privateMethod2() { }
// public (non virtual) methods
this.publicNonVirtual1 = function() { return privateVar1; }
this.publicNonVirtual2 = function() { return privateVar2; }
},
// public methods (that cannot access privates)
publicVirtual1: function() { /* Cannot access privates here. */ },
publicVirtual2: function() { /* Cannot access privates here. */ }
});
This less then ideal for several reasons:
No protected level
I can have public members that can access private members or public members that can be overridden but not not public member that can access private members and be overridden.
My public methods that can be overridden are not prototyped.
I've done some searching but haven't found anything that suggests I can do better without altering how prototype works. Here's some of the more interesting links:
Using Prototype’s Class.create to define private/protected properties and methods
JavaScript private methods
Private Members in JavaScript
Again with the Module Pattern – reveal something to the world
I've seen it suggested that you can provide accessors for my public virtual methods to use by doing something like this:
Message = Class.create({
initialize: function(message)
{
var _message = message;
this.getMessage = function() { return _message; }
this.setMessage = function(value) { _message = value; }
},
printMessage: function() { console.log(this.getMessage()); },
appendToMessage: function(value) { this.setMessage(this.getMessage() + value); }
});
This clearly will not work as intended. The goal is to only allow printing and appending to the message from outside of the object. The setter provided to make the virtual public function work also allows full control of the message. It could be changed to make the virtual method little more then a shell as follows:
Message = Class.create({
initialize: function(message)
{
var _message = message;
this._printMessage = function() { console.log(_message); }
this._appendToMessage = function(value) { _message += value; }
},
printMessage: function() {this._printMessage(); },
appendToMessage: function(value) { this._appendToMessage(value); }
});
This new version does limit public access for this class but is somewhat redundant. Not to mention if appendToMessage is overriden in a subclass a third party can still call _appendToMessage to access the original method which is not good.
I do have a very dirty idea that will get me close but is a can of worms I'd rather not open. I may post it later but in the mean time does anyone have suggestions for merging the two types of public methods into one useful type or on how to implement protected members.
EDIT:
I suspect the lack of feedback (aside from bobince's don't bother comment) mean that I am correct in that you can't take it any farther but I think I'll clarify a little just in case. I don't think it is possible to get anything close to the protection of other languages. I'm more interested in knowing where the limits lie and how accurate my understanding of the principles involved are. I do however think it would be interesting, if not useful, if we could get the various protection levels functioning to the point that non public members don't show up in a for...in loop (or in Prototypes Object.keys which uses for..in) even if it people who know what they are doing can still break the rules by doing things like tinkering with my prototypes. Afterall, its like bobince says " they have no-one to blame but themselves"
Now to comment on an issue raised by bobince:
Even if you made real
private/protected variables it still
wouldn't get you the full
encapsulation an effective security
boundary would require. JavaScript's
ability to fiddle with the prototypes
of built-in types your methods will be
using gives an attacker the ability to
sabotage the methods.
This is one limitation I do understand and I probably should have mentioned above. However, I am not looking at this from the point of view of protecting my code from someone trying to "hack" it. However, I do have a few things that may be worth noting (or in need of correcting if I am wrong):
Only my public members are vulnerable in this way.
If my public virtual methods are "compromised" in this way, then the "compromised" methods will still not have access to the private members.
If my public (non virtual) members are "compromised" in this way, then, unlike the original version of the method, the "compromised" version will not have access to the private memebers.
As far as i know the only way to gain accesses to the private members by methods defined outside of initialize method is too take advantage of a bug in the way some browsers handle eval calls.
How to make a protected member in JavaScript: put an underscore at the start of the name.
Seriously, you're not going to have security boundaries within a JS script that would make real proper protection necessary. Access levels are a trad-OO coder's obsession that make no sense in the context of web scripting. Even if you made real private/protected variables it still wouldn't get you the full encapsulation an effective security boundary would require. JavaScript's ability to fiddle with the prototypes of built-in types your methods will be using gives an attacker the ability to sabotage the methods.
So don't bother try. Just do like the Pythoners do: flag the method as something outsiders shouldn't be calling, and be done with it. If someone uses your code and relies on a member with _ at the start of the name, that's their problem and they have no-one to blame but themselves when their script breaks. Meanwhile you'll make the development and debugging stages easier for yourself by not having strict private and protected members.
Then you can choose per-instance-members (for callback binding convenience) or prototyped members (for efficiency), whether or not you intend them to be private, and you won't trip yourself up on the inconsistency.
http://www.crockford.com/javascript/private.html
Explains it all...

Categories

Resources