I have a function in javascript
var fn = function(){
var obj = {result: true};
return obj.result;
};
I have access to the function, but I need to get the inner obj. Is there a way to do that?
EDIT: Thanks to the answers below, I have managed to come up with a solution.
https://stackoverflow.com/users/1447675/nina-scholz 's answer was the closest, so I marked it as the solution.
var f2 = function fn(){
fn.obj = {result: true};
return fn.obj.result;
};
A client of this function can use it like the following :-
var myFunction = f2;
The function must be called though, to access the inner variables
myFunction();
After that one can do the following.
console.log(myfunction.obj);
This seems to be working. I would, however like to know if this is a good practice.
You cannot access the inner object outside of the scope of the function.
you can access obj when you make it public.
function fn() {
fn.obj = { result: true };
return fn.obj.result;
}
console.log(fn());
console.log(fn.obj.result);
Related
Everything is in the the title really... I know that functions created using prototype can't have access to private object data/functions, but what about having access to the arguments that were passed to the object when it was created ?
var Voice = function (word)
{
/*
I know I can obviously do something like : 'this.word = word;'
But I was wondering whether there is a standard way of calling an
argument from within a prototype function without having to do
the above ?
*/
};
Voice.prototype.speak = function ()
{
console.log({{word}});
};
x = new Voice('all I can say is this');
x.speak();
Thanks!
No.
The functions on the prototype weren't defined within the function that the variables are in scope for, so they don't have access to them.
You can store the variable as an object property and then read it back from there.
this.word = word;
Maybe like this:
var Voice = function (word) {
this.init_word = word;
};
Voice.prototype.speak = function (){
console.log(this.init_word);
};
x = new Voice('all I can say is this');
x.speak();
function abc(){
//multiple variables and functions
a:function(){alert("a")};
}
function test(){
var k=abc();
k.a();
}
In the above case, I have a huge function abc() to be assigned to a variable. I want to call the member functions that are visible, like a() from the variable. Is this possible to implement and please give me a sample code if so.
When you include the parenthesis after your function, you're assigning the result of the function to your variable.
If you want to assign the function itself, just omit the parenthesis:
var k = abc;
k.a();
EDIT
Per #Kuba Wyrostek's answer, and #Pointy's comment, that a() function won't be properly exposed.
You'll need to take a look at the Module Pattern. What you need to do is to assign a function to a variable, and have that function return the functions that you want to be able to use outside of that function. This helps with encapsulation.
It's a little hard to tell from your code in the comment exactly what is the user-generated code, but I'll do my best.
var abc = (function () {
var grabApi,
initialize;
// Just an example of how to assign an existing function
// to a property that will be exposed.
grabApi = SCORM2004_GrabAPI();
// This is an example of how to have a property that will be
// exposed be a custom function passing a parameter.
initialize = function(initString) {
return SCORM2004_GrabAPI().Initialize(initString);
};
return {
getApi: grabApi,
init: initialize
}
}());
You can then use this abc object like this throughout your code. Again, this is trying to give an example of how to do what I think you're trying to do based on your comment.
// Assign the SCORM2004_GrabAPI function to a variable.
var SCORM2004_objAPI = abc.getApi();
// Call the Initialize function with an empty string.
abc.init("");
Hmmm… contrary to #krillgar's answer, I believe you were expecting your abc() to return new object. Something like this:
function abc(){
var privateVar;
return {
//multiple variables and functions
a:function(){alert("a")}
}
}
function test(){
var k=abc();
k.a();
}
You should make it an object. In this way you can access its property a.
var abc ={
a:function(){alert("a")}
}
function test(){
var k=abc;//Ofcrse remove the parenthesis
k.a();
}
test();
Is it possible to create an alternate of Array.forEach that automatically sets the context "this" to be the same context as when the method was invoked?
For example (not working, not sure why):
Array.prototype.each = function(fn) {
return this.forEach(fn, arguments.callee.caller);
}
function myFunction() {
this.myVar = 'myVar';
[1,2,3].each(function() {
console.log(this.myVar); // logs 'myVar'
});
}
Array.forEach already takes a context argument as the optional last parameter,
(function() {
this.myvar = "myvar";
[1,2,3,4].forEach(function(v) {
console.log("v:"+v);
console.log("myvar="+this.myvar);
}, this);
})();
See MDN forEach
Also, the above examples (if we're not dealing with methods on instances regarding this) work without using bind or the optional context argument for forEach, the following also works correctly:
function myFunction() {
this.myVar = 'myVar';
[1,2,3].forEach(function() {
console.log(this.myVar); // logs 'myVar'
});
}
myFunction();
Because javascript is functionally scoped, so the anonymous function can access the parent function's scope using this and it logs correctly. this only really becomes problematic as a context when dealing with instance methods.
The answer is no, a JavaScript function cannot determine the value of this in the caller.
You can bind the function passed with the current object, like this
function myFunction() {
this.myVar = 'myVar';
[1,2,3].forEach(function() {
console.log(this.myVar); // logs 'myVar'
}.bind(this));
}
In ECMA Script 6, you can use an Arrow function, like this
[1,2,3].forEach(() => {
console.log(this.myVar); // logs 'myVar'
});
An alternative to messing with the this variable when passing around callbacks, you could always just assign this to a new variable so child scoped functions can access it:
Array.prototype.each = function(fn) {
return this.forEach(fn, arguments.callee.caller);
}
function myFunction() {
var me = this;
me.myVar = 'myVar';
[1,2,3].each(function() {
console.log(me.myVar); // logs 'myVar'
});
}
now you don't have to remember to pass this as a second parameter
Firstly, it must be pointed out that myFunction is a constructor. Yet, the first letter in the identifier is not capitalized. Please call it MyFunction.
If a constructor is called without the new operator, this is bound to the global object, i.e. window in browsers. This makes the capitalization convention our only way of spotting such mishaps.
The following lines of code demonstrate this:
// After the original code...
myFunction();
console.log(window.myVar); // logs "myVar"
Secondly, to be able to apply functions on any array, instead of changing Array.prototype, consider the following:
var utils = {array: {}}; // utils.array is a container for array utilities.
utils.array.each = function (array, func) {
var i;
for (i = 0; i < array.length; i += 1) { func(array[i]); }
};
utils.write = function (s) {
console.log(s); // Alternatively, document.write(s);
};
utils.array.each([1, 2, 3], utils.write); // prints 1 2 and 3 (on separate lines)
Notice that we didn't use this and new. They make JavaScript look like Java, apart from that, they rarely serve a useful purpose.
While libraries may modify Object.prototype and Array.prototype, end-developers shouldn't.
Also, we should (ideally) be able to do something like:
utils.array.each([1, 2, 3], console.log); or
utils.array.each([1, 2, 3], document.write);.
But most browsers won't allow it.
Hope this helped.
If I understand your requirement correctly, then you are trying to override the "this".
I think this can help you.
This question is simplified version of my old question Adding scope variable to a constructor. Question is simple can I add priv variable to the fu()'s scope without changing the function? (not adding inside of the function block)
Here is fiddle
Here is the code:
fff = function() {
alert('constructed');
//alert(priv);
};
pro = {
pub: 'public'
}
var make = function(fu, pro) {
var priv = 'private';
fu.prototype = pro
return function() {
return new fu();
};
};
var cls = make(fff, pro);
var obj = cls();
alert(obj.pub);
As you can see if you de-comment the
//alert(priv);
line Uncaught ReferenceError: priv is not defined error.
I need a way to redifine the scope of the fu() function object.
I don't see the fu object listed, but I think the answer is "yes", you can add a private variable without changing the "function". Now, I may be missing something, but if I follow you, here is what you want:
var fu = {
DoStuff: function(someVar){
alert(someVar);
}
};
Then later in your code:
fu["NewPrivateVar"] = "something!";
Or in dot notation:
fu.NewPrivateVar = "someting!";
Finally:
fu.DoStuff(fu.NewPrivateVar);
Results in:
"something!"
Is that what you are looking to do?
You can't change the scope of the function by calling it from inside an object or a closure.
You can however add the variable to the scope of the function, i.e. in the global scope:
window.priv = 'private';
That will make the function work without changes, but the variable isn't very private...
I'm learning javascript and one thing I keep hearing is "functions are objects". Can you provide some examples for me to better understand this concept?
Sure. Here's some example code:
function Hello() {
alert(Hello.world);
}
Hello.sayHello = Hello;
Hello.world = 'Hello, world!';
Hello.sayHello.sayHello.sayHello.sayHello.sayHello();
Here's proof that it works, too.
Notice how you can assign properties to the function, and assign it to itself and refer to it recursively. It's an object, like most other things in JavaScript, and you can do anything with it. If you've seen prototype inheritance before:
Function.prototype.alert = function() {
alert(this.apply(null, arguments));
};
function add(a, b) {
return a + b;
}
add.alert(1, 2); // Alerts 3
There's a lot here - a function literal, which is a function without a name in essence; prototypical inheritance; methods on functions; dynamic arguments; a function as this.
Here's a quick example on jsBin: http://jsbin.com/enicaj/edit#source
Basically, since functions are objects, they can also have properties and methods.
EDIT: JavaScript inline.
function test(){
return 'hello';
}
test.method = function(){
return ' world';
};
document.write( test() + test.method() );
Outputs 'hello world';
var sayHi = function() {
console.log("hi!");
};
var anotherFunction = function(functionObject) {
functionObject();
};
The function "sayHi" is passed as an object as an argument into the "anotherFunction" function and invoked.
anotherFunction(sayHi);
Use a javascript console like the one included in Chrome to observe this jsFiddle example.
Simplest example of var- function with parameter.
var x = function(message){
alert(message);
};
x('hello world');
x('hello again');
JSFiddle
Yes, you can write a function:
function MyFunction()
{
}
but you can also write
var MyFunction = function()
{
}
you can call both using MyFunction();. There are different reasons for writing them each way, both have their benefits.
Example 1: the function is globally accessible even if you can it before it's defined.
Example 2: the function is extendable as such.
var MyFunction = function()
{
// private methods/properties for use inside object
var privateProperty = 'privatevalue';
var privateFunction = function()
{
return '';
}
// public methods/properties for use outside object
this.propertyName = 'value';
this.publicFunction = function()
{
return privateProperty;
}
}
You can call the public data from the function just as you would an object.
var myobject = new MyFunction()
myobject.publicFunction();
// returns privatevalue;
But the privateProperty var you cannot access.
myobject.privateProperty // will returned undefined variable privateProperty
You can define properties and even methods/functions within the object (function).
That was very much a crash coarse but I hope it helps you understand it a bit more.