var foo = function(){};
foo.prototype.value = 5;
foo.prototype.addValue = function(){ foo.value = 6; }
function bar(func)
{
func(); // I'm running the function!
}
bar(foo.addValue); // pass in the function
alert(foo.value); // it's now 6!
Why is the no alert prompt when running this JavaScript code?
The correct code should be
var foo = function(){};
foo.prototype.value = 5;
foo.prototype.addValue = function(){ foo.value = 6; }
function bar(func)
{
func(); // I'm running the function!
}
bar(foo.prototype.addValue); // pass in the function
alert(foo.value);
or
var foo = function(){};
foo.prototype.value = 5;
foo.prototype.addValue = function(){ foo.value = 6; }
function bar(func)
{
func(); // I'm running the function!
}
bar(new foo().addValue); // pass in the function
alert(foo.value);
Since you are declaring a prototype called addValue, foo itself does not contain addValue. To refer to that function, you have to use foo.prototype.addValue. Note that in this case, foo contains both foo.prototype.value with a value of 5, and foo.value with a value of 6.
Alternatively, if the intention is to create a new object, then the object will inherit the addValue function, so calling new foo().addValue works.
Well, refactoring your code would give:
var foo = {
value: 5,
addValue: function(){
foo.value = 6;
}
};
function bar(func){
func(); // I'm running the function!
}
bar(foo.addValue); // pass in the function
alert(foo.value); // it's now 6!
Setting foo.prototype.addValue won't help you to define foo.addValue.
And the reason for using foo.value instead of this.value is to resolve scope problems when calling via bar()
Related
An example of this question is like this
var bar = (function(){
function foo(){
alert("foo");
}
function test(){
var f = "foo";
// I want to run f() to run the function foo
}
})();
If the function is in the global scope I can run it using window["foo"]() or if namespaced window["namespace"]["foo"]() but how can I run it inside like the example? I don't want to use eval().
A much clear example of what I want is like this:
var fns = ['a','b','c'],
bar = (function(){
function a(){
alert("a");
}
function b(){
alert("b");
}
function c(){
alert("c");
}
function test(array){
for(var i;i<array.length;i++){
//I want to run the functions that is on the array
// something like window[array[i]]() if function is in the global scope
}
}
return {
test : test
}
})();
bar.test(fns);
You can create a local object to reference the function, then access its property as you would with your window example.
var bar = (function(){
function foo(){
alert("foo");
}
var obj = {
foo: foo
};
function test(){
var f = obj["foo"];
f();
}
test();
})();
That's as close as you're going to get in a local scope without using eval.
You can create the object OR fn with this operator and make it an function with new constructor.
Creating an object.
https://jsfiddle.net/0Lyrz6rm/6/
var bar = {
foo: function(){
alert("foo");
},
test: function(){
var f = "foo";
return f;
}
}
bar["foo"]();
console.log(bar["test"]());
Another alternate way is to define the function as with constructor and little modification.
https://jsfiddle.net/0Lyrz6rm/4/
var bar = function(){
this.foo = function(){
alert("foo");
};
this.test = function(){
var f = "foo";
return f;
// I want to run f() to run the function foo
}
this.test2 = {
f: "foo"
}
}
var f = new bar();
f["foo"]();
console.log(f.test());
console.log(f.test2.f);
I have three simple programs below with different outputs. I am a bit confused as to why I get a different output. What really happens when you assign a function to a variable? Does it not run unless you have parentheses (i.e. myfunction())? I'm also very confused as to how JavaScript allows the parenthesis behind a function as 'optional' when calling it. Can someone clear this up? I only know Java so this is all new territory for me.
// ------First--------------------------------
var x = 9;
function myfunction (){
x = 3;
}
var w = myfunction;
w();
console.log(x);
//output is 3
// ---------Second -----------------------------
var x = 9;
function myfunction (){
x = 3;
}
var w = myfunction;
console.log(x);
//output is 9
// ---------Third -----------------------------
var x = 9;
function myfunction (){
x = 3;
}
var w = myfunction();
console.log(x);
//output is 3
No, it does not. A reference to a function by name is simply a reference to a value, like any other value. Without the () operator, it's not a function call.
Parentheses are not optional when calling a function except when it's being called via the new operator. Thus:
function foo() {
console.log("hi!");
}
var otherFoo = foo; // no function call
var obj = new foo; // function call via "new"
var x = foo(); // function call via "()"
I try to figure out, how closure works, this is my example
function func1(func) {
return function(summand) {
return func() + summand;
}
}
var func2 = function() {
return 3;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
var func2 = function() {
return 100;
}
var newValue = func3(100);
alert(newValue);
First of all let breaks down the code. I write a function that expected as parameter a function and it will return a function.
function func1(func) {
return function(summand) {
return func() + summand;
}
}
Then i defined the parameter function func2 in expression form
var func2 = function() {
return 3;
}
then call func1 and give func2 as pamerater. As result i have got a function back
var func3 = func1(func2);
then i execute function and pass 4 as parameter argument
var value = func3(4);
as result i've got 7. Then i overwrite func2 and return 100
var func2 = function() {
return 100;
}
then call func3 again and pass as parameter value 100.
var newValue = func3(100);
as result i've got 103. The first function that i defined(that return a function and takes function as parameter), will still used the first version of func2. This the power of closure, i know it.
But look at the following code, when i define func2 as function declaration not as expression, then func2 will overwrite
function func1(func) {
return function(summand) {
return func() + summand;
}
}
function func2() {
return 3;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
function func2() {
return 100;
}
var newValue = func3(100);
alert(newValue);
The first value is 104 and second is 200.
My question is, why when i use function declaration it will overwrite the old function, in this example is func2. But when i use function expression it will keep the reference to old func2.
It that because of function hoisting?
This is not because of closures.
Just like you figured out - this issue is because of function hoisting.
You can think of function declarations as "moved up" to the start of the current scope.
var f2 = function(){
return 50;
}
function f2(){
return 100;
}
In this case, f2 is 50 because it gets parsed in a way that's similar to:
var f2 = function(){
return 100;
}
var f2 = function(){
return 50;
}
Because of hoisting.
It is because of hoisting. Using the function statement rather than the function expression causes the function func2 to get hoisted to the top of the scope. You are overwriting func2 before any code in the scope gets executed.
because of hoisting you code actually looks like this:
function func1(func) {
return function(summand) {
return func() + summand;
}
}
function func2() {
return 3;
}
// Hoisted!!! Overwriting the previous func2 definition.
function func2() {
return 100;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
var newValue = func3(100);
alert(newValue);
Inside func1, func is a stable reference to the function that it was passed... It's just that you are passing the return 100; version before you think you are.
When you use the function foo() { ... } style, you are defining a function with the name foo. When you use the var foo = function() { ... } style, you are declaring a variable foo (which will be hoisted), and assigning it the anonymous function as its value.
It is ok to write
var a;
a = 2;
// ...stuff...
a = 3;
and we expect the value to be 3. So it is here, hoisting makes this like:
var func2;
func2 = function() { .. some stuff.. };
// ...stuff...
func2 = function() { .. some other stuff .. };
By comparison, I think if you define the functions, it will just take the one or other function definition in the initial parse.
I want to add another function called myFunction() into the CoreTeamObject, which is declared as local inside the anonymous function. Is this possible?
!function ($) {
var CoreTeamObject = function () {
var coreTeamVar1; // ...
this.someState = false; // ...
coreTeamFunction: function () { /* ... */ }
};
}(window.jQuery);
Normally, I'd use prototype with something like:
CoreTeamObject.prototype.myFunction = function(){
return
};
But I simply don't know how to access the object.
You simply can't. Variables within a function are private and cannot be accessed from the outside.
! function () {
var foo = 1;
}();
// Calling `foo` will throw a referenceError here.
// It doesn't even work with classes...
var foo = function () {
var bar = 2;
};
var bax = new foo();
// `bax.bar` doesn't exist.
However, there are workarounds. You could store them in a global variable (bad idea, though):
! function (w) {
w.foo = 3;
}(window);
// window.foo = 3
// foo = 3
Or if you can rewrite it to a class:
var foo = function () {
this.bar = 4;
};
var bax = new foo();
// bax.bar = 4
I hope this helps.
var foo = function () { this.bar = 1; }
>> foo.bar
undefined
How do I access the property of a function?
You syntax is wrong:
function foo() { this.bar = 1; }
var a = new foo();
a.bar; // 1
That is a definition. You need to instantiate it.
var foo = function () { this.bar = 1; }
>> new foo().bar
Another option:
var foo = function () { this.bar = 10; return this; } ();
console.log(foo.bar);
Read about self executing functions here:
What is the purpose of a self executing function in javascript?
The problem here is that you've only defined foo and not actually executed it. Hence the line this.bar = 1 hasn't even run yet and there is no way for bar to be defined.
The next problem is that when you run foo it will need a context which this will be defined in. For example
var x = {}
foo.apply(x);
x.bar === 1 // true
Or alternatively you could run foo as a constructor and access bar on the result
var x = new foo();
x.bar === 1 // true