Javascript OOP - Best practices when validating objects via interface or prototype - javascript

I am learning more advanced OO tactics for javascript coming from a C# background and am wondering about how to or if its even a good idea to implement prototype based validation. For instance when an object or function requires one of its parameters to satisfy a certain interface, you could check its interface like so,
var Interface = function Interface(i) {
var satisfied = function (t, i) {
for (var key in i) {
if (typeof t !== 'object') {
return false;
}
if (!(key in t && typeof t[key] == i[key])) {
return false;
}
}
return true;
}
this.satisfiedBy = function (t) { return satisfied(t, i); }
}
// the interface
var interfacePoint2D = new Interface({
x: 'number',
y: 'number'
});
// see if it satisfies
var satisfied = interfacePoint2D.satisfiedBy(someObject);
I came up with this strategy to validate an object by its interface only, ignoring the internal implementation of the object.
Alternatively say you are using prototype-based inheritance, should you or should not validate parameters based on their prototype functions? I understand that you'd use a prototype to implement default functionality whereas an interface doesn't specify any default functionality. Sometimes the object you are passing into a function might need certain default functionality in order for that function to work. Is it better to only validate against an interface, or should you ever validate against a prototype, and if so, whats the best way to do it?
EDIT -- I am providing some more context as to why I am asking this,
Say for instance in online game design (games written mostly in javascript). There are 2 main reasons I am interested in validation within this context,
1) Providing a strong public API for modding the game if desired
2) Preventing (or atleast discouraging greatly) potential cheaters
Which requires a balance between customizability and abuse. Specifically one situation would be in designing physics engine where objects in the game react to gravity. In a realistic system, users shouldn't be able to add objects to the system that do not react to gravity. The system has a function that expresses the global effect of gravity at any given point:
function getGravityAt(x, y) {
// return acceleration due to gravity at this point
}
And objects which react have a method that uses this to update their acceleration:
function update() {
this.acceleration = getGravity(this.position);
}
The minimum thing to do might be to ensure that any object added to the system has an 'update' method, but you still aren't ensuring that the update() method really is intended to react to gravity. If only objects that inherit from a prototypical update() method are allowed, then you know at least to some degree everything in the system reacts realistically.

This is a pretty subjective question. I'll pass on the question of whether it's a good idea to do interface-based validation in Javascript at all (there may well be good use-cases for it, but it's not a standard approach in the language). But I will say that it's probably not a good idea to validate objects based on their prototypes.
If you're validating by interface at all, you're probably working with objects created by other programmers. There are lots of ways to create objects - some rely on prototypes, some do not, and while they each have their proponents, they're all valid and likely approaches. For example:
var Point = function(x,y) {
return {
x: function() { return x },
y: function() { return y }
};
};
var p = new Point(1,1);
The object p conforms to an interface similar to yours above, except that x and y are functions. But there's no way to validate that p satisfies this interface by inspecting its constructor (which is Object()) or Point.prototype. All you can do is test that p has attributes called x and y and that they are of type "function" - what you're doing above.
You could potentially insist that p has a specific ancestor in its prototype chain, e.g. AbstractPoint, which would include the x and y functions - you can use instanceof to check this. But you can't be sure that x and y haven't been redefined in p:
var AbstractPoint = function() {};
AbstractPoint.prototype.x = function() {};
AbstractPoint.prototype.y = function() {};
var Point = function(x,y) {
var p = new AbstractPoint(x,y);
p.x = "foo";
return p;
}
var p = new Point(1,1);
p instanceof AbstractPoint; // true
p.x; // "foo"
And perhaps more importantly, this makes it harder to drop in custom objects that also satisfy the interface but don't inherit from your classes.
So I think what you're currently doing is probably the best you can hope for. In my experience, Javascript programmers are much more likely to use on-the-fly duck-typing than to try to mimic the capabilities of statically typed languages:
function doSomethingWithUntrustedPoint(point) {
if (!(point.x && point.y)) return false; // evasive action!
// etc.
}

I'll reiterate, type checking is not idiomatic javascript.
If you still want type checking, Google's closure compiler is the implementation I recommend. Type checking is done statically :) It has conventions for interfaces as well as (proto)type checking.

Related

Understanding functor laws: is this a functor?

The following code is written in javascript.
This question involves an attempt to dive into some category theory, maybe a haskeller or someone more familiar with the mathematical aspects of this question can help me out?
I'm trying to wrap my head around the idea that a functor is a mapping between categories that preserves structure. More specifically - according to my understanding - a functor in a programming language is an endofunctor. By this it is meant that functors in programming languages are morphisms that map types and functions to a sub-category within the broader category of types and functions as defined generally within the programming language.
According to my knowledge, functors (or endofunctors) must also adhere to certain laws that afford preservation of structure via the facilitation of composition and identity.
I'm finding it almost impossible to create a functor that I feel preserves structure, and adheres to the functor laws. This is compounded by the fact that I've only really programmed seriously in javascript, so type theory is something I've never really thought about (JS is untyped after all).
I made this simple example that lifts integers into a minimal context where mappings won't work on even numbers. In other words, you can map away with your composition but as soon as you hit an even number the show is over.
This looks sort of like a Maybe:
class noEvens {
constructor(x) {
this._val = x;
}
static of(x) {
return new noEvens(x);
}
isEven() {
return this._val % 2 === 0;
}
map(projF) {
return this.isEven() ? noEvens.of(null) : noEvens.of(projF(this._val));
}
}
But it's evident that this won't commute with compositions applied to integers in the normal JS category under certain situations. Consider a projection function that simply adds one to an integer.
If I lift an even number into this noEvens context and then add one it will give me a noEvens of null. But, if I first add one to an even number, then lift the result, it will result in a noEvens of an odd Number.
According to my understanding, both of these pathways should commute under functor laws. They clearly don't because the same mappings through each context don't result in the same resultant "noEvens.of(value)" after being lifted.
So I guess my question is, does this mean that this is not a functor? What is it about this type of situation (type-wise or whatever) that makes it act strangely?
I guess I'm just confused because it seems to be that all "noEvens" does is lift values into a new context (sub-category, whatever) where even numbers don't exist, but it is obvious that certain pathways won't commute.
I find the idea of "lifting a value" into a new mapping context quite intuitive, and it affords you a lot of opportunities to deal with conditions without having to implement tonnes of redundant code. But I don't want to do so in the false pretense that I'm adhering to some formalized system of "functor laws".
What is it about type-systems and functor laws that I'm missing in my analysis of this situation?
In addition to my comment...
You may notice that your almost-functor class also doesn't satisfy the identity law.
const id = x => x;
new noEvens(2).map(id) // != new noEvens(2)
My first thought was that the mistake was allowing a noEvens object containing an even number to be constructed in the first place. If the isEven check was instead done in the constructor, then you could satisfy the ID law.
class noEvens {
constructor(x) {
if (x % 2 === 0) {
this._val = null;
} else {
this._val = x;
}
}
static of(x) {
return new noEvens(x);
}
map(projF) {
if (this._val === null) {
return noEvens.of(null);
}
return noEvens.of(projF(this._val));
}
}
const id = x => x;
new noEvens(1).map(id)._val // ok: 1
new noEvens(2).map(id)._val // ok: null
But, it turns out this solution still doesn't satisfy the composition law.
const plusOne = x => x + 1;
// fmap f . fmap g == fmap (f . g) ?
new noEvens(1).map(plusOne).map(plusOne)._val // null
new noEvens(1).map(x => plusOne(plusOne(x)))._val // 3
So ultimately I think the fatal flaw is that noEvens limits what kind of data it can hold. As Bergi also said, "A usual functor would be capable of containing any arbitrary data." So noEvens, at its core, as a concept, cannot be a functor that obeys the composition law.

Memory handling vs. performance

I'm building a WebGL game and I've come so far that I've started to investigate performance bottlenecks. I can see there are a lot of small dips in FPS when there are GC going on. Hence, I created a small memory pool handler. I still see a lot of GC after I've started to use it and I might suspect that I've got something wrong.
My memory pool code looks like this:
function Memory(Class) {
this.Class = Class;
this.pool = [];
Memory.prototype.size = function() {
return this.pool.length;
};
Memory.prototype.allocate = function() {
if (this.pool.length === 0) {
var x = new this.Class();
if(typeof(x) == "object") {
x.size = 0;
x.push = function(v) { this[this.size++] = v; };
x.pop = function() { return this[--this.size]; };
}
return x;
} else {
return this.pool.pop();
}
};
Memory.prototype.free = function(object) {
if(typeof(object) == "object") {
object.size = 0;
}
this.pool.push(object);
};
Memory.prototype.gc = function() {
this.pool = [];
};
}
I then use this class like this:
game.mInt = new Memory(Number);
game.mArray = new Memory(Array); // this will have a new push() and size property.
// Allocate an number
var x = game.mInt.allocate();
<do something with it, for loop etc>
// Free variable and push into mInt pool to be reused.
game.mInt.free(x);
My memory handling for an array is based on using myArray.size instead of length, which keeps track of the actual current array size in an overdimensioned array (that has been reused).
So to my actual question:
Using this approach to avoid GC and keep memory during play-time. Will my variables I declare with "var" inside functions still be GC even though they are returned as new Class() from my Memory function?
Example:
var x = game.mInt.allocate();
for(x = 0; x < 100; x++) {
...
}
x = game.mInt.free(x);
Will this still cause memory garbage collection of the "var" due to some memcopy behind the scenes? (which would make my memory handler useless)
Is my approach good/meaningful in my case with a game that I'm trying to get high FPS in?
So you let JS instantiate a new Object
var x = new this.Class();
then add anonymous methods to this object and therefore make it a one of a kind
x.push = function...
x.pop = function...
so that now every place you're using this object is harder to optimize by the JS engine, because they have now distinct interfaces/hidden classes (equal ain't identical)
Additionally, every place you use these objects, will have to implement additional typecasts, to convert the Number Object back into a primitive, and typecasts ain't for free either. Like, in every iteration of a loop? maybe even multiple times?
And all this overhead just to store a 64bit float?
game.mInt = new Memory(Number);
And since you cannot change the internal State and therefore the value of a Number object, these values are basically static, like their primitive counterpart.
TL;DR:
Don't pool native types, especially not primitives. These days, JS is pretty good at optimizing the code if it doesn't have to deal with surprizes. Surprizes like distinct objects with distinct interfaces that first have to be cast to a primitive value, before they can be used.
Array resizing ain't for free either. Although JS optimizes this and usually pre-allocates more memory than the Array may need, you may still hit that limit, and therefore enforce the engine to allocate new memory, move all the values to that new memory and free the old one.
I usually use Linked lists for pools.
Don't try to pool everything. Think about wich objects can really be reused, and wich you are bending to fit them into this narrative of "reusability".
I'd say: If you have to do as little as adding a single new property to an object (after it has been constructed), and therefore you'd need to delete this property for clean up, this object should not be pooled.
Hidden Classes: When talking about optimizations in JS you should know this topic at least at a very basic level
summary:
don't add new properties after an object has been constructed.
and to extend this first point, no deletes!
the order in wich you add properties matters
changing the value of a property (even its type) doesn't matter! Except when we talk about properties that contain functions (aka. methods). The optimizer may be a bit picky here, when we're talking about functions attached to objects, so avoid it.
And last but not least: Distinct between optimized and "dictionary" objects. First in your concepts, then in your code.
There's no benefit in trying to fit everything into a pattern with static interfaces (this is JS, not Java). But static types make the life easier for the optimizer. So compose the two.

How to avoid using `this` pointer in JavaScript?

I am reading about prototipcal inheritance. There, and from elsewhere, I am learning this style of avoiding classical inheritance which I am still digesting.
One aspect that still puzzles me, though, is the this pointer, which is said to cause confusion for many like myself who come from classic OO languages. (If I were to avoid classic inheritance, shouldn't I be avoiding this as well?
)
After some reading, I realize that the this pointer is defined not at the time of object/function definition (as in C++) but rather at the site of function call. The this pointer seems (to me) like a dangling pointer whose target depends on where/how you use it.
Using an example in the linked blog article about extending objects, can someone help explain the following:
Can we avoid using this or replacing it with explicit object reference?
A related question is, is the this pointer necessary if I only use prototypical inheritance?
Example from the blog:
It would be nice to combine these two operations into one, ... and
extend it with new properties. This operation, called extend, can be
implemented as a function:
1 Object.prototype.extend = function (extension) {
2 var hasOwnProperty = Object.hasOwnProperty;
3 var object = Object.create(this);
4
5 for (var property in extension)
6 if (hasOwnProperty.call(extension, property) ||
7 typeof object[property] === "undefined")
8 object[property] = extension[property];
9
10 return object;
11 };
Using the above extend function we can rewrite the code for square as
follows:
1 var square = rectangle.extend({
2 create: function (side) {
3 return rectangle.create.call(this, side, side);
4 }
5 });
6
7 var sq = square.create(5);
8
9 alert(sq.area());
Note, this is used in line 3 of both code segments.
If you want to avoid this completely, then you should step away from creating methods that act on the object they are applied on, meaning that you should not have method calls like obj.method(), where method needs to use the state of obj in some way.
So the effect of the following should be the same as obj.method():
var method = obj.method;
method();
In places where the above would fail, you'll need to refactor the code, so that you can in principle use it like this without problems:
var method = obj1.method;
method(obj2); // apply method on obj2
So, in general you'll need to create utility functions that take one more argument: the object to apply the logic on.
In your case this would mean that you don't define extend on Object.prototype (which is considered bad practice anyway), but on Object itself, and give it the extra source object parameter. This is also how many native methods are defined, like Object.assign, Object.keys, et al. Also the definition of rectangle will need some changes to make it work without ever using this:
Object.extend = function (source, extension) {
var hasOwnProperty = Object.hasOwnProperty;
var object = Object.create(source);
for (var property in extension)
if (hasOwnProperty.call(extension, property) ||
typeof object[property] === "undefined")
object[property] = extension[property];
return object;
};
var rectangle = {
create: function (width, height) {
var self = {
width: width,
height: height,
area: function () {
return self.width * self.height;
}
};
return self;
}
};
var square = Object.extend(rectangle, {
create: function (side) {
return rectangle.create(side, side);
}
});
var sq = square.create(5);
console.log(sq.area());
As you have realised, there are lots of ways to work with objects and implement some form of inheritance in JavaScript, and each has its pros and cons.

Javascript: encapsulating state, exposing behaviour

I'm trying to improve my Javascript fundamentals so I can explore client-side frameworks (Knockout, Angular etc) and make progress in learning Node.js.
I've taken a simple problem which I use in teaching C# and I'm trying to solve it with Javascript.
The Problem
Create probability objects with an internal value for percentage of likelihood. For example, a 2/5 probability would be created with:
var firstOne = new Probability(40); // 2/5 is a 40% chance
That internal state should not be accessible through the instance variable. The purpose of the Probability function/object is to encapsulate the ability to compare one against another:
var secondOne = new Probability(30);
var areTheyEqual = firstOne.SameAs(secondOne); // returns false in this example
In C# this is relatively straight forward. The value of probability is stored in a member variable with private scope, and the SameAs function is public scope. Because each instance uses the same type, Probability, C#'s scoping allows the calling member to also 'see' the passed member's private state:
// C#
public class Probability
{
private int _value;
public Probability(int percent)
{
_value = percent;
}
public bool SameAs(Probability other)
{
return this._value == other._value; // works even though _value is private
}
}
I wondered if this kind of encapsulation could be achieved with Javascript. As a secondary question, perhaps what I'm trying to do is driven from a C# and OO perspective, where Javascript may offer alternative approaches to solve the problem that take advantage of Javascript's functional abilities. I'm open to both types of response.
You can work JavaScript closures to get close to what you're use to in other object oriented languages, e.g. something like:
function Probability() {
// private field
var _value = 0;
this.getValue = function() {
return _value;
};
this.setValue = function(newValue) {
_value = newValue;
};
this.sameAs = function(compare) {
return _value === compare.getValue();
};
}
var probability = new Probability();
probability.setValue(10);
var newProbability= new Probability();
newProbability.setValue(11);
console.log(probability.sameAs(newProbability)); // false
newProbability.setValue(10);
console.log(probability.sameAs(newProbability)); // true
You can find a lot of referencess when googling for Object-oriented JavaScript, I can recommend this site

Using components in Javascript

I'm relatively new to Javascript. I was wondering if it supports components and objects like Python does. If it does, what would the syntax look like?
For instance, I know an object look like this:
function Foo(a, b) {
this.a = a;
this.b = b;
}
Now, is there a way to declare some components, pick one of those, and add it to the object? For instance, let's say I have a object Item. Could I declare some different components, such as Weapon, Magical, Legendary, etc. and them add them to the object? Using this approach I could end up with a Magical Weapon, or a Legendary Item, or even a Legendary Magical Weapon.
I thought about using parenting for this but for what I want to do, it seems like that would be rather limited. For instance, my heirarchy would look like Item/Weapon or Item/Legendary, so I couldn't have a Legendary Weapon.
So, are components possible in Javascript?
What you describe as a 'component' is more commonly called a class. What you describe as 'parenting' is more commonly called inheritance. You are spot on about the class hierarchy :)
Ok, so your base class in an Item. This item will have the basic attributes which all items in your game world must have. All objects in your game world will inherit from Item.
A Weapon is an Item. A MagicalItem is an Item. A LegendaryItem is an item. These three classes are all subclasses of Item.
Things get a little bit more tricky when you want a LegendaryMagicalWeaponItem. This is the essence of your question: Is multiple inheritance possible in JavaScript?
To paraphrase the Boondock Saints, you do not want multiple inheritance unless you are absolutely, positively sure that you need it. Why? It quickly leads to complications. For example, what if two superclasses have a method or an attribute with the same name? What if they inherit from two different base classes, and one of those classes causes a name collision? You can see where this is going.
Fortunately, JavaScript, like Python, is a very flexible language. You are not forced to use multiple inheritance or even interfaces to generalise behaviour across heterogeneous objects.
Let's say MagicalItem has a mana property and LegendaryItem has a legacy() method. Let's say a weapon object has a damage. Let's say Item has important physical attributes and a bunch of physics methods; it is clearly the 'dominant' superclass. There is nothing stopping you from doing this:
// Base classes
function Item() {
// some default values...
}
Item.prototype.physics = function (t) {/* physics stuff */}
function Magical(mana) {
this.mana = mana;
}
function Weapon(damage) {
this.damage = damage;
}
function Legendary(legacy) {
this.legacy = function () {return legacy;};
}
// Actual world item class
function MyLegendaryMagicalSword(x,y) {
this.x = x;
this.y = y;
Weapon.call(this, MyLegendaryMagicalSword.DAMAGE);
Legendary.call(this, MyLegendaryMagicalSword.LORE);
Magical.call(this, MyLegendaryMagicalSword.START_MANA);
}
// actual prototypal inheritance
MyLegendaryMagicalSword.prototype = new Item();
// class attributes
MyLegendaryMagicalSword.DAMAGE = 1000;
MyLegendaryMagicalSword.START_MANA = 10;
MyLegendaryMagicalSword.LORE = "An old sword.";
// Sword instance
var sword = new MyLegendaryMagicalSword(0, 0);
sword.physics(0);
sword.mana;
sword.legacy();
// etc
// probe object for supported interface
if (sword.hasOwnProperty("damage")) {
// it's a weapon...
}
This is a down and dirty way to do what you describe.
> sword
{ x: 0,
y: 0,
damage: 1000,
legacy: [Function],
mana: 10 }
I have no idea what you mean by components. The term is too generalized. In Delphi, a component is a non-visible code module which introduces some special functionality to the application. A "timer" is one such example of a component (in Delphi).
Guessing from your description, you seem to want to add properties dynamically? Or is it about overloading?
In the latter case, you can't do this by design, as in, it lifts the limitations you mentioned.
Example (mixing):
function mixItems(weapon,legend){
return {
"damage":legend.damage+weapon.damage,
"name":legend.name+"' "+weapon.name
};
}
var weapon={ "damage":45, "name":"sword"};
var legend={ "name":"Goliath", "damage":34 };
var LegendaryWeapon = mixItems(weapon,legend);
console.log( LegendaryWeapon );
// output:- name: "Goliath's sword", damage: 79
Example (extending):
function clone(old){ // non-deep cloning function
var res={};
for(i in old)
res[i]=old[i];
return res;
}
var sword = {
"damage":50
"hit": function(){ // returns the percentage hit chance
return Math.round(Math.random()*100);
}
};
var bigsword=clone(sword);
bigsword.damage=60;
bigsword.hit=function(){ // returns the percentage hit chance
return Math.round(Math.random()*80)+20;
};
an object in javascript looks like this:
var Foo = {
a: null,
b: null,
init: function(a,b){
this.a = a;
this.b = b;
}
}
//call the init:
Foo.init(12,34);
almost the same as you have in the question.
And this object is extendable
you code example is a Function object which is intended to be used as a constructor function i.e. call it with the new keyword and it returns an instance of an object that has an a property and a b property (amongst other inherited properties).
Function objects inherit from Object like all other objects in JavaScript.
Usually, objects are created using object literal syntax, i.e. var x = { a: 'a', b: 'b' }; although they can also be created by using the new keyword with Object.
It looks like your question is referring to inheritance with JavaScript. Well, there are many ways to perform inheritance. One example is
function A() { }
function B() { }
B.prototype = new A;
Here both A and B are constructor functions. Functions have a prototype property which is an object and can contain members that can be shared by all object instances constructed by the function. We assign an instance of an object returned by the constructor function A to B's prototype, giving B all members available on an instance of A. This is just one way to perform inheritance in JavaScript.
The Mozilla Developer Center article on the Object Model is worth a read.

Categories