Solution:
Yay, using this.setName() worked!
Problem:
1) Didn't know how to properly title this question
2) I am trying to call a setName() from inside of getName()
Javascript:
window.login
chat = {
setName: function( ) {
},
getName( ) {
//i want to call setName() here, is that possible?
//i tried chat.setName() and setName(), both failed.
}
}
Very simple question, I just am not too knowledgeable in JavaScript. Thank you for the suggestions/help/advice!
Use this. It refers to the current object:
chat = {
setName: function() {
alert('setName');
},
getName: function() {
this.setName();
}
};
you can use the 'this' keyword.
var chat = {
setName: function(){...},
getName: function(){ this.setName(); }
};
chat = {
setName: function( ) {
alert('test');
},
getName: function( ) {
this.setName();
}
};
chat.getName();
You have a syntax error. Try:
chat = {
setName: function() {...},
getName: function() {
chat.setName();
}
}
Related
I'm trying to implement native bind functionality. However, when I try to test it out, I'm not getting the expected output.
Can someone tell me where am I going wrong?
Function.prototype.myBind = function(...args) {
const self = this;
return function() {
return self.apply(this, args);
}
};
function demo() {
return {
name: 'James Bond',
printName: function (args) {
console.log(this.name, args);
}
};
}
const test = {
name: 'Aqua Man'
};
console.log(demo().printName.myBind(test)('2020'));
// expected
console.log(demo().printName.bind(test)('2020'));
You need to bind to argument like this:
Function.prototype.myBind = function(binder) {
const self = this;
return function() {
return self.apply(binder, arguments);
}
};
I am trying to get the name of the parent function of the function being called.
For example if I have these functions:
var functions = {
coolfunction1: {
add: function () {
},
delete: function () {
},
save: function () {
}
},
coolfunction2: {
add: function () {
// i want to console.log() the name of the parent of this function,
// output: coolfunction2
},
delete: function () {
},
save: function () {
}
}
}
When I call functions.coolfunction2.add(), is there a way to log the name of the parent function that was run?
I know I can use the variable this but that only outputs the names of the children functions, add(), delete(), save().
How can I know that the coolfuntion2 was run?
I know this can be done manually, by rewriting the function name in the add() function, but is there a way to get the name dynamically?
You can add a getter to those methods as
Object.keys(functions).forEach(t =>
Object.keys(functions[t]).forEach(t2 => {
var func = functions[t][t2]; //save a reference to function since it won't be a function anymore once a getter is assigned
Object.defineProperty(functions[t], t2, {
get: function() {
console.log(t); //print the name of parent property or grand-parent property, etc
//func();
return func; //return the reference to this function
}
});
})
);
Demo
var functions = {
coolfunction1: {
add: function() {
},
delete: function() {
},
save: function() {
}
},
coolfunction2: {
add: function() {
console.log("a is invoked");
},
delete: function() {
},
save: function() {
}
}
};
Object.keys(functions).forEach(t =>
Object.keys(functions[t]).forEach(t2 => {
var func = functions[t][t2];
Object.defineProperty(functions[t], t2, {
get: function() {
console.log(t);
//func();
return func;
}
});
})
);
functions.coolfunction2.add();
functions.coolfunction2.add();
functions.coolfunction1.add();
Sometimes in JavaScript I need many constructors and objects for pseudo-classes because I like objective very much so I do something like:
var anyClass = (function (settings) {
var staticPrivate = {}, staticPublic = function () {
var public = this, private = {};
(function constructor (here, the, args) {
this.hta = [here, the, args, arguments];
}).apply(this, arguments);
arguments = undefined;delete arguments;
private.stuff = function () {}
Object.defineProperties(public, {
"e.g. length": {
get: function () {
return private.length;
},
set: function (newValue) {
return;
},
enumerable: false
}
});
};
Object.defineProperties(staticPublic, {
"staticFinalHiddenString": {
get: function () {
return "YEAH, I'm static and final and hidden...";
},
set: function (newValue) {
return "You cannot set me.. :P";
},
enumerable: false
}
});
staticPrivate.some = function (init) {
if (settings.some == "settings") init();
}
window.requestAnimationFrame(function () {
staticPrivate.some(function (I) {
run(on, first, render);
});
});
return staticPublic;
})({
some: "settings",
here: null
});
And that every time, so now I want a constructor that creates a new class for me. I think on this:
new Class({
constructor: function (here) {
is(my + constructor);
},
properties: {
name: {
getter: function () {},
setter: function (newValue) {},
hidden: false,
static: false,
final: false
},
version: {
getter: function () {
return 0.3;
},
setter: function (newValue) {},
hidden: true,
static: true,
final: true
}
}
});
but my problem is that I have no idea how to create an prototype/constructor with an constructor class.prototype.prototype does not work.
I just tried that:
var Class = (function () {
var Class = (function () {
var constructor = function () {
return (function (information) {
this.prototype = {};
var properties = {};
for(var key in information.properties) {
properties[key] = {
get: information.properties[key].getter,
set: information.properties[key].setter,
enumerable: !information.properties[key].hidden || true
};
};
Object.defineProperties(this.prototype, properties);
return this;
}).apply(this, arguments);
};
return constructor;
})();
return Class;
})();
That does not work for me :C
I hope you can help me. Thanks...
I understood my mistake and now I can return somthing when I have an constructor.
The var Class = function () {}; and the Class.prototype in the closure function with .apply(this, arguments) does the thing, that is why I can return Class in the constructor function, if I would just do
var Class = function () {
var ClassICreate = function () {};
...
return ClassICreat;
}
it would not work, because you cannot return from a constructor, because it is an object.
That is how it works for my:
var Class = (function () {
var Class = function () {
return (function (information) {
var Class = function () {};
var properties = {};
for(var key in information.properties) {
properties[key] = {
get: information.properties[key].getter,
set: information.properties[key].setter,
enumerable: !information.properties[key].hidden || true
};
};
Object.defineProperties(Class.prototype, properties);
return Class;
}).apply(this, arguments);
};
return Class;
})();
After I found the answer it looked so easy to me, and thanks for the comments, they helped my to find the right answer...
I'm running into an issue with using RequireJS and Prototypal inheritance. Here's my module:
define(function () {
function Module(data) {
this.data = data;
}
Module.prototype.getData = function () {
return this.data;
};
Module.prototype.doSomething = function () {
console.log(this.data);
console.log(this.getData());
};
return Module;
Module.prototype.callFunction = function (fn) {
if (this[fn]) {
console.log('call');
Module.prototype[fn]();
}
};
});
Then I instantiate the module, like so:
var module = new Module({ name: 'Marty' });
module.getData(); // returns { name: 'Marty' }
module.data; // returns { name: 'Marty' }
module.callFunction('doSomething') // returns undefined on the first (and second) console log
The console.logs in the module.doSomething() always return undefined. Am I misunderstanding how prototypal inheritance works with RequireJS?
As it turns out, I had written the callFunction method incorrectly. The correct way is:
Module.prototype.callFunction = function (fn) {
if (this[fn] && typeof this[fn] === "function") {
this[fn]();
}
};
The problem was using Module.prototype instead of this. Whoops.
I made a simple example of my problem with a babel object :
function babel(){
this.english = {
hello: function () { alert('hello'); },
goodbye: function () { alert('goodbye'); }
teeshirt: function () { alert('T-shirt'); }
}
}
Now, I want to extends this object :
babel.prototype.french = {
bonjour: function () { alert('bonjour'); },
aurevoir: function () { alert('au revoir'); }
}
But what if I need to use an existing function define before ?
babel.prototype.french = {
bonjour: function () { alert('bonjour'); },
aurevoir: function () { alert('aurevoir'); },
teeshirt: function () { this.english.teeshirt(); }
}
What I could do is :
var say = new babel();
(function (_this) {
babel.prototype.french = {
bonjour: function () { alert('bonjour'); },
aurevoir: function () { alert('aurevoir'); },
hello: function () { _this.english.hello(); }
}
})(say);
But in this case, I will always use the context of the say object, isn't it ?
The problem is, that in teeshirt function call this points to the french object, not babel object. If you have to access parent object, you should store reference to it somewhere. For example you can change your constructor like this:
function babel(){
this.english = {
parent: this,
hello: function () { alert('hello'); },
goodbye: function () { alert('goodbye'); }
teeshirt: function () { this.parent.french.something(); }
}
}
But as you can see, there is a problem if you don't create object in constructor. I don't see any 'nice' approach, but you can do this:
function babel(){
this.english = {
parent: this,
hello: function () { alert('hello'); },
goodbye: function () { alert('goodbye'); }
teeshirt: function () { this.parent.french.something(); }
};
for (var i in babel.prototype) {
this[i].parent = this;
}
}
Then your french will look like this:
babel.prototype.french = {
bonjour: function () { alert('bonjour'); },
aurevoir: function () { alert('aurevoir'); },
teeshirt: function () { this.parent.english.teeshirt(); }
}
While the question as asked does bring up all the fascinating issues with JavaScript's this and prototypal inheritance, I would suggest simplifying the whole problem and refactoring your objects. There are a couple ways to do this.
If the English version of teeshirt is the default, it should be in the object which is at the end of the prototype chain. That is, a French object would have as its prototype an English object. The French object would simply not contain a teeshirt member. This is similar to the way resource bundles work.
Now this idea may not work for you, because the relationship among the different bundles may be complex: perhaps sometimes Engish is a fallback sometimes but not other times. In this case, see if you can make your babel objects all singletons (i.e., just plain objects).
var babel = {}
babel.english = {
hello: function () { alert('hello'); },
goodbye: function () { alert('goodbye'); },
teeshirt: function () { alert('T-shirt'); }
}
babel.french = {
bonjour: function () { alert('bonjour'); },
aurevoir: function () { alert('aurevoir'); },
teeshirt: function () { babel.english.teeshirt(); }
}
babel.english.teeshirt();
babel.french.teeshirt();
Try it at http://jsfiddle.net/yRnLj/
I realize this looks like a complete avoidance of your interesting question. But if you only need one copy of each language bundle, it is a lot simpler. :-)