Invoke a method in an Object that was created inside a function - javascript

I am confused by this question and not even the JavaScript MDN is clarifying the concept for me.
There is a function called invokeMethod and in that function I have to create an Object. The Object includes a Method. I need to invoke the Method in the Object using bracket notation but nothing needs to be returned.
Here is the Question and my code. I keep getting error messages when I try to call the method in the function parentheses.
Question: method is a string that contains the name of a method on the object
Invoke this method using bracket notation.
Nothing needs to be returned.
Input Example:
{ foo: function() {} }, 'foo'
My code:
function invokeMethod(object, method) {
// code here
const obj = {
name: 'kung',
foo: function(){
console.log('foo');
}
};
}
invokeMethod(obj[foo]);

Check if this help.
function invokeMethod(object, method) {
// object definitions
const obj = {
name: 'kung',
foo: function(){
console.log('foo');
}
};
// conditional invokation
switch(object){
case "obj":
if(typeof obj[method] == "function") return obj[method]();
default:
console.log("Given object not found!");
}
}
// call method
invokeMethod("obj", "foo");
***If the object itself is to be passed as parameter:
function invokeMethod(object, method) {
if(typeof object[method] === "function")
object[method]();
else
console.log('Invalid function name!');
}
invokeMethod({ foo: function() {console.log('foo');} }, 'foo');

Maybe this could help.
Look at your function I'm seen that you have as arguments two elements object and method. So, your functions it's bad doing this
function invokeMethod(object, method) {
// code here
const obj = {
name: 'kung',
foo: function(){
console.log('foo');
}
};
}
if you are going to receive the obj-function, you should have just this,
function invokeMethod(method)
Now, Following your example, I'm going to think that you really want to receive the obj-function. So, in that case, you should do this.
const obj = {
name: 'kung',
foo: function(){
console.log('foo');
}
};
function invokeMethod(obj, method) {
if((method in obj) && typeof obj[method] ==="function"){
return obj[method]();
}
}
invokeMethod(obj, 'foo');

Related

javascript: call method on dynamically generated object name

How would one call a method on a dynamically generated name? This is a case where I am passing the object name into a function and calling a method on that object. Something like this, where type is the name of the object I want to execute the method on:
function doSomething(type) {
type.someMethod();
}
Note that I do not want to pass the object into the function.
First, it is not clear what object that "type" belongs to. I'm guessing this is in scope, maybe something like this:
var typeObjects = {
type1: {
doSomething: function(){..},
..
},
type2: {
doSomething: function(){..},
..
},
..
}
Then, your function becomes the following:
function doSomething(typeName) {
typeObjects[typeName].someMethod();
}
And then you would call it like so:
doSomething('type1');
If your object is global, you could do this :
var global = global || window;
function doSomething(type) {
global[type].someMethod();
}
var myObject = {
someMethod : function () { console.log("calling someMethod") },
};
doSomething("myObject");
If you want to pass a variable name to a function, consider instead passing a property name of a predetermined object, so that your function is not unsafely accessing arbitrary objects from its scope with eval(), which is a bad practice for both security and performance reasons.
var myObject = {
foo: { someMethod () { console.log('fooObj') } },
bar: { someMethod () { console.log('barObj') } }
}
function doSomething (property) {
if (myObject.hasOwnProperty(property)) {
myObject[property].someMethod()
}
}
doSomething('foo')
doSomething('bar')
doSomething('nil') // does nothing
You need to eval the object name or method.
eval(type)['someMethod']();
or
eval(type + '.someMethod()');
Also if your object is at window scope, you can do
window[type].someMethod();

Javascript call one object method after another [duplicate]

This question already has answers here:
How can I chain my method calls?
(5 answers)
Closed 6 years ago.
I have this object:
const Foo = {
bar(x) {
},
baz(x) {
},
}
How can I rewrite this object to be able to call it's methods like this:
Foo.bar(x).baz(y);
instead of calling them like this:
Foo.bar(x);
Foo.baz(y);
Like in the jQuery where you can call one function after another...
$('bac').addClass('x').removeClass('y');
You will have to return the object itself with each function, so as you could call the function on it again (that's also what jQuery does).
const Foo = {
bar(x) {
return this;
},
baz(x) {
return this;
},
}
You should return this at the end of each function. In this context this refers to the Foo object itself.
const Foo = {
bar(x) {
return this;
},
baz(z) {
return this;
}
}
Example:
Foo.bar(x).baz(z);
is executed as:
Foo.bar(x) // <-- returns 'Foo'
.baz(z) // <-- call 'baz' function of 'Foo'
You Should Return The Object Itself From The Method To Call Another Method Again:
const Foo = {
bar(x) {
alert("BAR");
return this;
},
baz(x) {
alert("BAZ");
return this;
},
}
onload = function() {
Foo.bar().baz();
}
This is known as a Fluent API
In software engineering, a fluent interface (as first coined by Eric Evans and Martin Fowler) is an implementation of an object oriented API that aims to provide more readable code.
A fluent interface is normally implemented by using method cascading (concretely method chaining)
In this case it is implemented by returning the self-object this:
const foo = {
bar(x) {
console.log("bar")
return this; // here
},
baz(x) {
console.log("baz")
return this; // and here
}
}
foo.bar(10).baz(20);

How do concatenated function calls in JavaScript work?

I just saw this code example from the crypto-library of node.js and wondered how this kind of "concatenated" function-calls are implemented?
crypto.createHash('sha256').update(password).update(salt).digest('base64');
The return value of one function is an object (probably the original object, this here). A property of that object is another function.
var myObj = {
foo: function() {
alert("foo");
return this;
},
bar: function() {
alert("bar");
return this;
}
};
myObj.foo().bar().bar().foo().bar();

How to call a method from another method within the same object in JavaScript?

I'm just getting started in OO javascript so please bear with me.
This works:
var myObj = {
foo : function() {
alert('hello');
this.bar();
},
bar: function() {
alert('world');
}
}
However if I do some other stuff after the hello alert in the "foo" method then the meaning of "this" changes from the object to whatever I last selected so using this.bar() doesn't execute the other method in the class.
So I tried to cache "this" in a variable like so:
var myObj = {
publicVars: {
theObj : this
},
foo : function() {
alert('hello');
publicVars.theObj.bar();
},
bar: function() {
alert('world');
}
}
But that didn't work either. So what is the solution?
EDIT
Here is my actual code:
var formObj = {
validate : function(theForm) {
$('input, textarea', theForm).each(function() {
var valueLength = $(this).val().length;
if (valueLength === 0) {
$(this).addClass('invalid');
this.listenForInput($(this)); // <!------- this isn't working
}
});
},
listenForInput : function(theField) {
// theField.keyup(function() {
// if ($(this).val().length > 0) {
// theField.removeClass('invalid');
// }
// });
alert('I work!!!!');
}
} // end obj
As I said in my comment, you have to keep a reference inside the function:
validate: function(theForm) {
var self = this;
$('input, textarea', theForm).each(function() {
var valueLength = $(this).val().length;
if (valueLength === 0) {
$(this).addClass('invalid');
self.listenForInput($(this));
}
});
},
You are passing a function to each. Inside this callback, this refers to the DOM element. That's why you pass it to jQuery ($(this)) to be able to call jQuery methods on that element. It cannot refer to formObj too!
What this refers to is determined by how a function is called and each function has its own this (the Mozilla documention describes this in more detail).
If you call validate with formObj.validate(), then this refers to formObj.
The jQuery documentation for each states:
More importantly, the callback is fired in the context of the current DOM element, so the keyword this refers to the element.
Am I missing something, or can you not just reference the object by name, like this:
var myObj = {
foo: function() {
alert('hello');
myObj.bar();
},
bar: function() {
alert('world');
}
}
myObj.foo();
http://jsfiddle.net/karim79/kaXYj/
A function's this keyword is set by the call, it can't change during function execution.
Calling obj.foo() sets foo's this to obj so calling this.bar calls obj.bar. However, if you call foo some other way, e.g.:
var a = obj.foo;
a();
then its this will may be obj (in the above case it will be window or undefined in strict mode) so you get a different bar or an error if the this object doesn't have a bar property.

Refer to javascript function from within itself

Consider this piece of code
var crazy = function() {
console.log(this);
console.log(this.isCrazy); // wrong.
}
crazy.isCrazy = 'totally';
crazy();
// ouput =>
// DOMWindow
// undefined
From inside crazy() 'this' refers to the window, which I guess makes sense because normally you'd want this to refer to the object the function is attached to, but how can I get the function to refer to itself, and access a property set on itself?
Answer:
Don't use arguments.callee, just use a named function.
"Note: You should avoid using arguments.callee() and just give every function (expression) a name." via MDN article on arguments.callee
I think you are asking for arguments.callee, but it's deprecated now.
https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee
var crazy = function() {
console.log(this);
console.log(arguments.callee.isCrazy); // right.
}
crazy.isCrazy = 'totally';
crazy();
// ouput =>
// DOMWindow
// totally
As rfw said, this is the most straight forward way to go if the function has one single name:
var crazy = function() {
console.log(crazy);
console.log(crazy.isCrazy);
};
crazy.isCrazy = 'totally';
crazy();
In case it may have different names, or you wanted to pass it around, it must be wrapped in a closure:
var crazy = (function(){
var that = function() {
console.log(that);
console.log(that.isCrazy);
};
return that;
})();
crazy.isCrazy = 'totally';
crazy();
Bind the function to itself (taking a hint from answers by #ArunPJohny and #BudgieInWA):
crazy = crazy.bind(crazy);
This will give you access from the function to its properties via this.
> crazy()
function () {
console.log(this);
console.log(this.isCrazy); // works now
}
This seems like a better solution than the accepted answer, which uses the callee feature which is deprecated and doesn't work in strict mode.
You could also now have the function call itself recursively with this() were you so inclined.
We will call this self-thisifying. Write a little utility function:
function selfthisify(fn) { return fn.bind(fn); }
crazy = selfthisify(crazy);
crazy();
Or, if you prefer more "semantic" names, you could call it accessOwnProps.
If you're a syntactic sugar type of person, you could add a selfthisify property to the Function prototype:
Object.defineProperty(Function.prototype, 'selfthisify', {
get: function() { return this.bind(this); }
});
Now you can say
crazy.selfthisify();
You have to give it its own name, so:
var crazy = function() {
console.log(crazy);
console.log(crazy.isCrazy);
}
crazy.isCrazy = 'totally';
crazy();
The variable this is only applicable in the scope of an object, for instance, if you invoked your version of the crazy function with crazy.call(crazy), it will call the function in the context of the function crazy and all would be well.
This has to deal with the scope of the function crazy. If can pass any scope to a function using the function call().
Instead of
crazy();
Use
crazy.call(crazy);
For details refer
http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspxhttps://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Callhttp://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
You can use the call method
var crazy = function() {
console.log(this);
console.log(this.isCrazy);
}
crazy.isCrazy = 'totally';
crazy.call(crazy);
// calls crazy using crazy as the target, instead of window:
// functionToCall.call(objectToUseForThis);
Though if your function only ever has one name, you can do this:
var crazy = function() {
console.log(crazy);
console.log(crazy.isCrazy);
}
crazy.isCrazy = 'totally';
crazy();
Easiest way to make the function itself available in its body is to do
var crazy = function crazy2() { crazy2(); }, it's okay for crazy and crazy2 to have the same name since the first occurrence is the name in the outer scope and the second is the name in the function body.
Or simply do function crazy() { crazy(); } which will define crazy in both scopes.
how can I get the function to refer to
itself?
The idea of 'itself' does not exist with functions. What you need is an object and not just a function. An object has knowledge of itself available through the keyword 'this'. Within a function, 'this' points to the global object - in this case the window object. But if you use your function as a constructor function to create an object (using the new operator) then the object's 'this' pointer will point to the object itself.
i.e this points to the object if you write:
var anObject = new crazy();
So you can re-write your code as follows:
var crazy = function() {
this.printMe = function(){
console.log(this);
console.log(this.isCrazy);
}
}
var anObject = new crazy(); //create an object
anObject.isCrazy = 'totally'; //add a new property to the object
anObject.printMe(); //now print
In case you wish to add the property before the object is created, then you have to add the property to the function's prototype as follows:
var crazy = function() {
console.log(this);
console.log(this.isCrazy);
}
crazy.prototype.isCrazy = 'totally'; //add the property to the function's prototype
var anObject = new crazy(); //invoke the constructor
See more on my blog for a detailed explanation of these concepts with code-samples.
Are you actually trying to create an object 'class'?
function crazy(crazyState) {
this.isCrazy = crazyState;
console.log(this);
console.log(this.isCrazy);
}
crazy.prototype.alertMe = function() { alert('I am '+ this.isCrazy +' crazy.'); }
var crazyObj = new crazy('totally');
crazyObj.alertMe();
crazyObj.isCrazy = 'not';
crazyObj.alertMe();
Funny that you should ask, mate. I just went through this same issue for a different purpose. The quick version of the final code is:
$a = function() {};
$ = function() {
if (!(this instanceof $)) {
return new $();
}
this.name = "levi";
return this;
};
//helper function
var log = function(message) {
document.write((message ? message : '') + "<br/>");
};
log("$().name == window.name: " + ($().name == window.name)); //false
log("$().name: " + $().name); //levi
log("window.name: " + window.name); //result
log();
log("$a instanceof $: " + ($a instanceof $)); //false
log("typeof $a: " + (typeof $a)); //function
log("typeof $: " + (typeof $)); //function
The critical piece:
if (!(this instanceof $)) {
return new $();
}
If this isn't pointing to an object of the right type, then it makes a new one, which will properly scope this. The rest of the code is just there for verification that it does indeed work as intended.
In order to make you code to work follow below
function crazy_object (crazy) {
this.isCrazy = crazy
}
var create_crazy = new crazy_object('hello') //creating object
console.log(create_crazy); //=> { isCrazy = 'hello' }
var crazy = function() {
console.log(this); //=> { isCrazy = 'totally' }
console.log(this.isCrazy); //=> 'totally'
}
create_crazy.isCrazy = 'totally'; //=> isCrazy = 'totally'
//below we pass the created object in function crazy.
//And doing that we can use the keywork `this` and refer to the object
crazy.call(create_crazy, null);
Using the call and apply method we can pass to a function a
property,and in that function we can use the property with the keyword this
For example:
function speak (message) {
console.log(`A person with name ${this.name} say ${message}`);
}
speak.call({ name: 'Roland' }, 'Javascript is awesome');
To use it with property:
function speak (message) {
console.log(`A person with name ${this.name} say ${message}`);
}
var name = 'Roland'
speak.call({ name }, 'Javascript is awesome');

Categories