How to get interface name in implemented function - javascript

Below is the code I have used to achieve interface concept in javascript:
function Interface1(ImplementingClass) {
return {
implementedFunction : ImplementingClass.implementedFunction
}
}
function Interface2(ImplementingClass) {
return {
implementedFunction : ImplementingClass.implementedFunction
}
}
function ImplementingClass() {
this.implementedFunction = function() {
// How to get implemented interface name, for
// example here interface name should be Interface1???
}
}
function Test() {
this.test = function() {
return new Interface1(new ImplementingClass());
}
}
var test = new Test();
test.test().implementedFunction();
Question: How to get interface name in implemented function, for example in java we use instance of operator
if(this instance of Interface) {
// Do something
}

No, instanceof won't work - it's only for prototypical inheritance from a constructor function's prototype object. If you need information about your interface, you will need to place it on your interface object:
function Interface(implementingInstance) {
return {
interfaceName: "MyInterface",
implementedFunction : implementingInstance.implementingFunction
}
}
function ImplementingClass() {
this.implementingFunction = function() {
console.log(this.interfaceName);
}
}
/* maybe helpful:
ImplementingClass.prototype.interfaceName = "noInterface"; // real instance
*/
function Test() {
this.test = function() {
return Interface(new ImplementingClass());
}
}
new Test().test().implementedFunction();
// calls `implementingFunction` on the object with the `interfaceName` property

Related

Handle function in const class?

I have source code like this
const item = function(p) {
let model;
p.setup = function() {
}
}
I am not sure how should I call this class? function component?
What I want to do is add my function to this and call this function from outside.
const item = function(p) {
let model;
p.setup = function() {
}
function nextGame(){
console.log("test");
}
}
item.nextGame(); // error
However it doesn't work.
I am not familiar this style of javascript.
How should I add the function to this(is it class??) and call??
What you describe and demonstrate in your snippet javascript is an anonymous function, you could even say that it is a functional variable.
To access methods using dot notation, you need to create a class (or javascript object).
example using the keyword 'class':
class MyClass
{
var name;
var lastName;
constructor(_name, _lastname)
{
this.name = _name;
this.lastName = _lastname;
}
sayMyName()
{
window.alert(`${this.name} ${this.lastname}`);
}
}
Now create an instance of this class. Like this:
const myName = new MyClass("John", "Doe");
and now call with the method of your class using notation. Like this:
myName.sayMyName();
class Item {
// private field for whatever
// got passed to the constructor.
#value;
constructor(value) {
this.#value = value;
}
// prototypal methods with access to
// private fields and private methods.
setup() {
// do something with `this.#value`
console.log(this.#value);
}
nextGame() {
console.log("next game");
}
}
const item = new Item("OP's mysterious `p` value");
console.log({ item });
console.log('item.setup() ...');
item.setup();
console.log('item.nextGame() ...');
item.nextGame();
.as-console-wrapper { min-height: 100%!important; top: 0; }
For object-oriented programming in javascript there are a few methods, as mentioned in the comments.
1. Factory Function
A factory function is a simple approach, as it just creates and returns an object.
function Item(model) {
const item = {
model,
nextGame: () => { console.log('test') }
}
return item
}
const itemInstance = Item('Tesla');
itemInstance.nextGame()
console.log(itemInstance.model)
2. Constructor Function
Uses the new keyword to create an instance of the defined object type. It utilizes the function's prototype, which is accessible on all instances of the type.
function Item(model) {
this.model = model;
}
Item.prototype.nextGame = () => { console.log('test') }
const itemInstance = new Item('Tesla');
itemInstance.nextGame()
console.log(itemInstance.model)
3. Class
You could also use a Class. Classes in javascript are provided as an abstraction of functions.
class Item {
constructor(model) {
this.model = model
}
nextGame() {
console.log('test')
}
}
const itemInstance = new Item('Tesla');
itemInstance.nextGame()
console.log(itemInstance.model)

Calling property of One Function From Inside Another Javascript

I'm using functions as representations of classes.
function ClassOne()
{
this.doFunc = function() {
console.log("doFunc output");
}
}
function ClassTwo()
{
this.one = ClassOne();
console.log(this.one); // == undefined ???
this.init = function() {
this.one.doFunc();
}
this,init();
}
ClassTwo();
But I'm struggling to use one function inside another.
For example, the above code returns "Cannot read property 'doFunc' of undefined"
Why is this.one == undefined?
If you assign to a property of this inside a function, generally that indicates that the function is intended to be called as a constructor with new, eg:
this.one = new ClassOne();
Otherwise, if the function doesn't return anything... then, well, nothing gets returned (=> undefined)
function ClassOne()
{
this.doFunc = function() {
console.log("doFunc output");
}
}
function ClassTwo()
{
this.one = new ClassOne();
console.log(this.one);
this.init = function() {
this.one.doFunc();
}
this.init();
}
ClassTwo();
Or, you can have ClassOne explicitly return an object with a doFunc property, allowing it to be called without new:
function ClassOne()
{
return {
doFunc() {
console.log("doFunc output");
}
}
}
function ClassOne() {
return {
doFunc() {
console.log("doFunc output");
}
}
}
function ClassTwo() {
this.one = ClassOne();
console.log(this.one);
this.init = function() {
this.one.doFunc();
}
this.init();
}
ClassTwo();

Structuring helper functions

I'm creating an abstraction above a couple very similar, but different interfaces and can't decide on the best way to structure my code to keep is as DRY as possible. So I'm trying to refactor out all the similar code into their own functions, but aren't sure where to place these functions.
Current setup:
var module = function module( API ) {
var properties,
doSomething = function doSomething( config ) {
if (A) {
foo();
}
else if (B) {
// lotsa bar1 code
}
else if (C) {
// lotsa bar2 code
}
else {
error();
}
};
return {
// public interface
};
};
I would like to fold the bar1 and bar2 code into its own function, but can't decide where to place this function. I don't really want to cause overhead by declaring the helper inside the function it's helping, although it's the most readable option.
Option A: Make the helper function another direct method of the module.
This seems to be the easiest approach, but I don't like 'polluting' my main module namespace with functions
"that don't represent a method of the module."
edit: "that don't represent an action of the module."
var module = function module( API ) {
var properties,
bar = function bar() {
// help doSomething
},
doSomething = function doSomething( config ) {
if (A) {
foo();
}
else if (B) {
bar(B);
}
else if (C) {
bar(C);
}
else {
error();
}
};
return {
// public interface
};
};
Option B: Create a seperate namespace for all the helpers. This is how I usually structure these kinds of extra functions, but the more I use this version, the less satisfying it seems.
var module = function module( API ) {
var properties,
helpers = {
'bar' : function bar( input ) {
// help doSomething
}
},
doSomething = function doSomething( config ) {
if (A) {
foo();
}
else if (B) {
helpers.bar(B);
}
else if (C) {
helpers.bar(C);
}
else {
error();
}
};
return {
// public interface
};
};
Option C: Set the helper function as a method of the main function.
var module = function module( API ) {
var properties,
doSomething = function doSomething( config ) {
if (A) {
foo();
}
else if (B) {
doSomething.bar(B);
}
else if (C) {
doSomething.bar(C);
}
else {
error();
}
};
doSomething.bar = function( input ) {
// help doSomething
};
return {
// public interface
};
};
And option D would be to create a closure around the function.
Maybe I'm putting way too much thought in this and it's all a matter of preference.

Override privileged method of base class

How can I go about making a child class override a privileged method of a base class?
If its not possible, is there another way to achieve what I am trying to accomplish in the simple code example below?
I cannot convert the baseclass function parseXML() to public because it requires access to private variables
function BaseClass()
{
var map = {};
// I cannot make this function public BECAUSE it accesses & changes private variables
this.parseXML = function( key, value )
{
alert("BaseClass::parseXML()");
map[key] = value;
}
}
function ChildClass()
{
BaseClass.call(this);
this.parseXML = function( key, value, otherData )
{
alert("ChildClass()::parseXML()");
// How can I call the base class function parseXML()?
//this.parseXML(); // calls this function not the parent function
//MyClass.prototype.doStuff.call
BaseClass.prototype.parseXML.call(this, key, value); // fails
//BaseClass.prototype.parseXML(); // fails
// perform specialised actions here with otherData
}
}
ChildClass.prototype = new BaseClass;
var a = new ChildClass();
a.parseXML();
function BaseClass() {
var map = {};
this.parseXML = function(key, value) {
alert("BaseClass::parseXML()");
map[key] = value;
}
}
function ChildClass() {
BaseClass.call(this);
var parseXML = this.parseXML;
this.parseXML = function(key, value, otherData) {
alert("ChildClass()::parseXML()");
parseXML.call(this, key, value);
}
}
ChildClass.prototype = new BaseClass;
var a = new ChildClass();
a.parseXML();
Live Example
Basically you cache the privileged method (which is only defined on the object) and then call it inside the new function you assign to the privileged method name.
However a more elegant solution would be:
function BaseClass() {
this._map = {};
};
BaseClass.prototype.parseXML = function(key, value) {
alert("BaseClass::parseXML()");
this._map[key] = value;
}
function ChildClass() {
BaseClass.call(this);
}
ChildClass.prototype = Object.create(BaseClass.prototype);
ChildClass.prototype.parseXML = function(key, value, otherData) {
alert("ChildClass()::parseXML()");
BaseClass.prototype.parseXML.call(this, key, value);
}
var a = new ChildClass();
a.parseXML();
Live Example
Also bonus implementation using pd
IMO, you need to use a Javascript library like Ext Js to simplify this task. Anyway, the following example illustrates how you can write some helper methods. It's a part of an unreleased open source project that I'm working on.
var JWObject = (function () {
var jwobj = function (){};
jwobj.prototype = { };
return jwobj;
})();
var Prototype = (function () {
var scopeQueue = [ window ];
return {
beginScope: function (namespace) {
var parts = namespace.split('.');
for (var i = 0; i < parts.length; i++) {
var name = parts[i],
parent = this.getScope(),
part = parent[name];
if (part && !part.__namespace) {
throw Error('/* ERROR MESSAGE */');
}
scopeQueue.push(parent[name] = (part || { __namespace: true }));
}
},
endScope: function () {
if (scopeQueue.length > 1) {
scopeQueue.pop();
}
},
getScope: function () {
return scopeQueue.pick();
},
define: function (name, members) {
var scope = this.getScope();
if (scope[name]) {
throw Error('The prototype already exist.');
}
this.extend(members, {
scope: scope,
extend: JWObject,
statics: {}
});
// Getting constructor
var ctor = (members.constructor === Object) ? function() { } : members.constructor;
delete members.constructor;
if (typeof members.extend === 'string') {
members.extend = scope[members.extend];
}
if (!members.extend) {
throw Error('The base class is not specified.');
}
// Deriving from parent type
ctor.prototype = new members.extend();
members.super = members.extend.prototype;
delete members.extend;
members.statics.__class = true;
this.extend(ctor, members.statics, true);
delete members.statics;
// Adding new members
this.extend(ctor.prototype, members, true);
// Adding and returning the created prototype
return scope[name] = ctor;
},
extend: function (expando, members, override) {
for (var m in members) {
if (override || !expando[m]) {
expando[m] = members[m];
}
}
}
};
})();
Prototype.extend(Array.prototype, {
pick: function() {
return this[this.length - 1];
}
});
Here is the result:
Prototype.beginScope('Sample');
/**
* Prototype: Sample.Plugin
*/
Prototype.define('Plugin', {
init: function() {
alert('init!');
}
});
Prototype.beginScope('Extension');
/**
* Prototype: Sample.Extensions.Plugin
* Extend : Sample.Plugin
*/
Prototype.define('Foo', {
extend: Sample.Plugin,
init: function() {
this.super.init.call(this);
alert('child: init!');
},
fun: function() {
this.init();
},
statics: {
create: function() {
return new Sample.Extension.Foo();
}
}
});
Prototype.endScope();
Prototype.endScope();
As you can see in the preceding code, the Prototype object provides some functionality to defining a namespace (Prototype.beginScope, Prototype.endScope and Prototype.getScope) or defining a prototype (Prototype.define).
You can inherit a prototype from another using extend like java.
Prototype.define('Foo', {
extend: Sample.Plugin,
Or call the base class method as follows:
init: function() {
this.super.init.call(this);
Also, every prototype you define with above code will be derived from JWObject by default.

access parent object in javascript

var user = {
Name: "Some user",
Methods: {
ShowGreetings: function() {
// at this point i want to access variable "Name",
//i dont want to use user.Name
// **please suggest me how??**
},
GetUserName: function() { }
}
}
You can't.
There is no upwards relationship in JavaScript.
Take for example:
var foo = {
bar: [1,2,3]
}
var baz = {};
baz.bar = foo.bar;
The single array object now has two "parents".
What you could do is something like:
var User = function User(name) {
this.name = name;
};
User.prototype = {};
User.prototype.ShowGreetings = function () {
alert(this.name);
};
var user = new User('For Example');
user.ShowGreetings();
var user = {
Name: "Some user",
Methods: {
ShowGreetings: function() {
alert(this.Parent.Name); // "this" is the Methods object
},
GetUserName: function() { }
},
Init: function() {
this.Methods.Parent = this; // it allows the Methods object to know who its Parent is
delete this.Init; // if you don't need the Init method anymore after the you instanced the object you can remove it
return this; // it gives back the object itself to instance it
}
}.Init();
Crockford:
"A privileged method is able to access the private variables and
methods, and is itself accessible to the public methods and the
outside"
For example:
function user(name) {
var username = name;
this.showGreetings = function()
{
alert(username);
}
}
You can try another approach using a closure:
function userFn(name){
return {
Methods: {
ShowGreetings: function() {
alert(name);
}
}
}
}
var user = new userFn('some user');
user.Methods.ShowGreetings();
Old question but why can't you just do something like this :
var user = {
Name: "Some user",
Methods: {
ShowGreetings: function() {
// at this point i want to access variable "Name",
//i dont want to use user.Name
// **please suggest me how??**
var thisName = user.Name; //<<<<<<<<<
},
GetUserName: function() { }
}
}
Because you will only call user.Methods.ShowGreetings() after the user has been instantiated. So you will know about the variable 'user' when you want to use its name ?
As others have said, with a plain object it is not possible to lookup a parent from a nested child.
However, it is possible if you employ recursive ES6 Proxies as helpers.
I've written a library called ObservableSlim that, among other things, allows you to traverse up from a child object to the parent.
Here's a simple example (jsFiddle demo):
var test = {"hello":{"foo":{"bar":"world"}}};
var proxy = ObservableSlim.create(test, true, function() { return false });
function traverseUp(childObj) {
console.log(JSON.stringify(childObj.__getParent())); // returns test.hello: {"foo":{"bar":"world"}}
console.log(childObj.__getParent(2)); // attempts to traverse up two levels, returns undefined because test.hello does not have a parent object
};
traverseUp(proxy.hello.foo);
Very late to the party, but this works
var user = {
Name: "Some user",
Methods() {
return {
that: this,
ShowGreetings: function() {
console.log(this.that.Name)
},
GetUserName: function() { }
}
}
}
user.Methods().ShowGreetings() // Some user
David Dorward's right here. The easiest solution, tho, would be to access user.Name, since user is effectively a singleton.
ES6 Classes
One simple solution would be to create a Class with methods!
class User {
// Assign properties when an instance
// is created using the `new` keyword
constructor(name) {
this.name = name;
}
// Methods:
showGreetings() {
console.log(`Hello, ${this.name}!`);
}
getUserName() {
return this.name;
}
// Or rather, use Getters:
get username() {
return this.name;
}
}
// Create a new user:
const user = new User("Praveen");
// Use methods:
user.showGreetings(); // "Hello, Praveen!"
console.log(user.getUserName()); // "Praveen"
console.log(user.username); // "Praveen"
Why the above suggestion? Mostly because:
you cannot reference a parent Object from a child Object directly
const User = {
name: "Some user", // hardcoded stuff? Is this an intentional Singleton?
methods: { // <<< Child Object of User
sayName() {
// Sadly, `this` refers to `methods`, not to `user`:
console.log(this); // methods{}
console.log(User.name); // "Some user" // Get Singleton's name
// ... but that's not what you want.
}
}
};
User.methods.sayName();
// ^^^^^^^ Why would you want this `methods` anyways?!
and it makes no sense to hardcode Strings (like "Some user") inside an Object Singleton — which could actually be a reusable function Object.
If you want to associate a child Node to a parent Node — read this answer (Get value of parent Object).
How about this way?
user.Methods.ShowGreetings.call(user, args);
So you can access user.Name in ShowGreetings
var user = {
Name: "Some user",
Methods: {
ShowGreetings: function(arg) {
console.log(arg, this.Name);
},
GetUserName: function() { }
},
Init: function() {
this.Methods.ShowGreetings.call(this, 1);
}
};
user.Init(); // => 1 "Some user"
As a variant:
var user = (obj => {
Object.keys(obj.Methods).map(option => {
const currOpt = obj.Methods[option];
if (currOpt instanceof Function) {
obj.Methods[option] = currOpt.bind(obj);
};
});
return obj;
})({
Name: "Some user",
Methods: {
Greeting: function () { return this.Name },
GetUserName: function() { console.log(this) }
},
});
But I don't know why somebody can use this strange approach
I know I'm very late.
I wrote this simple method. Let's say you have:
{
subObj: {
x:'hello_world';
}
}
Then, if you want a reference to the bigger object from subObj, you can convert it to a function, and utilize this.
var tmpVal=reference_to_subObj; //keep value of subObj safe
reference_to_subObj=function(){return this;}//this returns the scope, here the parent
var parent=reference_to_subObj(); //call the function
reference_to_subObj=tmpVal; delete tmpVal; //set things back to normal
//Now you have variable 'parent'.
I used a Function() constructor because it let me create the function as a string, so I could pass a string as code.
function findParent(stringReference) {
Function(/*same as above, except filled in all reference_to_subObj with stringReference.*/
//stringReference is a stringified version of dot or bracket notation.
So I could call findParent('obj.subObj').
// Make user global
window.user = {
name: "Some user",
methods: {
showGreetings: function () {
window.alert("Hello " + this.getUserName());
},
getUserName: function () {
return this.getParent().name;
}
}
};
// Add some JavaScript magic
(function () {
var makeClass = function (className) {
createClass.call(this, className);
for (key in this[className]) {
if (typeof this[className][key] === "object") {
makeClass.call(this[className], key);
}
}
}
var createClass = function (className) {
// private
var _parent = this;
var _namespace = className;
// public
this[className] = this[className] || {};
this[className].getType = function () {
var o = this,
ret = "";
while (typeof o.getParent === "function") {
ret = o.getNamespace() + (ret.length === 0 ? "" : ".") + ret;
o = o.getParent();
}
return ret;
};
this[className].getParent = function () {
return _parent;
};
this[className].getNamespace = function () {
return _namespace;
}
};
makeClass.call(window, "user");
})();
user.methods.showGreetings();
I ran across this old post trying to remember how to solve the problem. Here is the solution I used. This is derived from Pro JavaScript Design Patterns by Harmes and Diaz (Apress 2008) on page 8. You need to declare a function and then create a new instance of it as shown below. Notice the Store method can access "this".
function Test() {
this.x = 1;
}
Test.prototype = {
Store: function (y) { this.x = y; },
}
var t1 = new Test();
var t2 = new Test();
t1.Store(3);
t2.Store(5);
console.log(t1);
console.log(t2);
Like #Quentin said, there is no upwards relationship in JS. However try this workaround;
foo = { bar: {parent: foo} };
console.log(foo);
console.log(foo.bar.parent);
which is also similar to;
function Foo(){
this.bar = {parent: this}
}
foo = new Foo();
console.log(foo);
console.log(foo.bar.parent);

Categories

Resources