Get Object Method Name From Within That Same Method - javascript

Let's say I have an obj:
var app = {}
and a method inside the object
app = {
init: function () {
}
}
how would I go about obtaining the method name 'init' inside of init() without specifically looking for 'init'. This would be in the case that the method name could be anything and I can't rely on searching for a specific name.
app = {
init: function () {
//get 'init' method name here
}
}
app.init();
I tried using callee but that brings back an empty string

You could use a named function expression:
app = {
init: function init() {
console.log(arguments.callee.name);
}
};
app.init(); // => "init"
Note that use of arguments.callee is forbidden in strict mode.
What you are doing in your example is assigning an anonymous function expression to the property named init on your object. The function itself does not have a name unless you use a named function expression.

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();

widget , call function from option error?

In the widget I'm trying to call a function from a property in the options
getThing: this._runFunc()
but I get an error saying _runFunc() is not an instance of an object? can you please help?
$.widget('my.testW', {
options:{
buttons:buttons,
getThing: this._runFunc() // why wont _runFunc work?
},
_create: function () {
//do things
var s = this.options.getThing;
},
_runFunc: function (){
return 'hello world'
}
});
In the $.widget call, the options object and the anonymous object literal within which it is contained are just parameters to $.widget, so this refers to whatever this was outside the $.widget call, and not the newly defined widget.
AFAIK, there's no way to refer to some other element of the same anonymous object literal from within values of that literal.
If you wish to hide your function, you could define your widget thus:
(function() {
function _runFunc() {
return 'hello world';
};
$.widget(..., {
options: {
getThing: _runFunc()
},
_runFunc: _runFunc; // if you want to expose this method
});
})();
where the IIFE encloses the utility function within that scope.

javascript prototype how to create object

I'm currently learning prototyping in javascript, i wrote the below and it seems to work fine when i use it. my question was why do i need the () at the end of the prototype declaration, without that if i try to make an instance of the object I get an error.
var MyTest = function (agencyId, dataId) {
this.agencyId= agencyId;
this.dataId= dataId;
};
MyTest.prototype = function () {
var setObservables = function () {
...
},
init = function (url) {
...
};
// public members
return {
init: init
};
}();
to use it I call it like
var obj = new DetailsDivisionKO(1, 2);
obj.init(actionUrl);
this works fine, but I'm confused about the }(); at the end of the public members section, why is that needed and I can not have that and still use the above code to call it? As without that if i try to call the above code I get a error stating:
Uncaught TypeError: Object [object Object] has no method 'init'
What you have is an IIFE. Its an imidiately invoked function. You are basically creating a closure. You are exposing your init function while preserving a true private scope to your setObservables function. So every time you create a new instance of the constructor, your init function will always be in the prototype. But setObservables will not. In your example you could only access setObservables function internally (hence private scope). Usually you would do that if you only want your init function to call your private functions which in your case is setObservables. But if this is not what you want, you simply can do this:
var MyTest = function (agencyId, dataId) {
this.agencyId= agencyId;
this.dataId= dataId;
};
MyTest.prototype = {
setObservables: function () {
...
},
init: function (url) {
...
}
}
Now every time you will create a new instance of MyTest, both of your functions will be in its prototype.
var test = new MyTest(1, 2);
test.init();
test.setObservables();

Namespace issue in javascript

The function name is mixed even if I am using a namespace. In the below example when I call nwFunc.callMe() or $.Test1.callTest() it will execute _testFunction() of doOneThing. I am expected for $.Test1.callTest() to call _testFunction() in $.Test1 API instead of one in doOneThing. What I need to do to correct it?
Example:
var doOneThing = function() {
_testFunction= function() {
...
}
return {
// public
callMe: function(){
_testFunction();
}
}
}
var nwFunc = doOneThing();
nwFunc.callMe();
$.Test1.callTest();
below is a example API
jQuery.Test1 = (function(){
_testFunction= function() {
...// do differently
}
return {
// public
callTest: function(){
_testFunction()
}
}
}(jQuery))
You're not in an object literal, you are in a function body.
_testFunction: function() {
.... // do differently
}
is not an object property, but an anonymous function expression preceded by a label and is immidiately forgotten as it is not assigned anywhere. Make it a simple function declaration instead:
function _testFunction() {
.... // do differently
}
And
return {
// public
callMe() {
_testFunction();
}
}
is just a syntax error, in here you need the object literal sytnax:
return {
// public
callTest: function() {
_testFunction()
}
};
or
return {
// public
callTest: _testFunction // exporting the function directly
};
When I call nwFunc.callMe() or $.Test1.callTest() it will execute _testFunction() of doOneThing. What I need to do to correct it?
You have to use a var declaration to put your _testFunction variable in a local scope. Currently you're writing to the global scope, where only one _testFunction exists (currently in doOneThing you're overwriting the _testFunction from jQuery.Test1, and both callTest functions will invoke the new one). A function declaration would've fixed this as well (using the local scope), it is similar to a var statement + function expression.
You are mixing up your syntax slightly. You are using object literal notation when you declare the function originally and using function declaration notation when actually creating the object, so you should switch the two:
jQuery.Test1 = (function(){
function _testFunction() {
.... // do differently
}
return {
// public
callTest: _testFunction
}
}(jQuery))

How to dynamically build a function in javascript

I want to create a function dynamically using javascript. I've started with the following:
function setFunc(setName){
var setName = function () {
};
}
setFunc("totop");
I want to set a function dynamically, but it doesn't work!
How can I fix this?
That won't work.
However, consider this: functions in JavaScript are just values and window is the top-level scope, so... (This assumes it is desired for the new function to be created in the top-level scope.)
function setFunc (name) {
window[name] = function () { alert("hi!") }
}
setFunc("a")
window.a() // "hi!" - explicit property access on object
window["a"]() // "hi!" - ditto
a() // "hi!" - window implicit as top-level
However, I do not recommend this sort of global side-effect...
Happy coding.
The question is, in which context you want to create that function. If you really want to create a global function with that name, do it like
function setFunc( setName ) {
this[ setName ] = function() {
alert('I am ' + setName);
};
}
setFunc('totop');
However, this is not a great idea to clobber the global object like that. Furthermore, the above code will break in es5 strict mode. However, by using the new keyword, you could create constructs like
new setFunc('foobar').foobar();
or just store the result in a variable
var myObj = new setFunc('BoyohboyWhatALongString');
console.log( myObj ); // BoyohboyWhatALongString() is in there now
Don't Use the eval function like this:
function setFunc(setName){
eval (setName + " = function () { };");
}
setFunc("toTop");
You can access the window scope as an associative array and define the function with that name:
function setFunc (name) {
window[name] = function () { }
}

Categories