Is there any way, in JavaScript, to write a function like:
var a = "Hello"
function change(variable, value) {
//Code that edits original variable, not the variable argument
}
alert(a)
change(a, "World!");
alert(a);
And this would output first "Hello", and then "World!". Is there any way to write a function like that?
No, but a close alternative is to treat a as a JS object:
var a = { value : "Hello" };
function change(variable, value) {
//I'll let you work this part out
}
alert(a.value);
change(a, "World!");
alert(a.value);
Here is how you do that by using JavaScript Closures;
var obj = (function() {
var x = 'hello';
return {
get: function() {
return x;
},
set: function(v) {
x = v; }
}
})();
obj.get(); // hello
obj.set('world');
obj.get(); // world
You can only the change the value of the variable using the get and set functions.
Related
Here is my code:
function myOuterFunction() {
myInnerFunction();
var myObject = {say: myInnerFunction.myProperty1,
say2: myInnerFunction.myProperty2
};
function myInnerFunction(){
return {myProperty1: "hello",
myProperty2: "world"
};
}
console.log(myObject);
}
myOuterFunction();
Why I am not able to geht the functions property?
I know I could solve this with another variable but why isnt this solution possible?
Thanks
You should store the value of the function before using it.
function myOuterFunction() {
var data = myInnerFunction();
var myObject = {
say: data.myProperty1,
say2: data.myProperty2
};
function myInnerFunction() {
return {
myProperty1: "hello",
myProperty2: "world"
};
}
console.log(myObject);
}
myOuterFunction();
your mistakes are
1) try not to use myInnerFunction() inside myOuterFunction(). it's not a good programming practice
2) calling myInnerFunction() does nothing when calling it out in the open. you are not even giving it's return value to a variable.
3) calling myInnerFunction without () doesn't tell javascript that the it is a function
this is the way you should write it
function myOuterFunction() {
var myObject = {say: myInnerFunction().myProperty1,
say2: myInnerFunction().myProperty2
};
console.log(myObject);
}
function myInnerFunction(){
return {myProperty1: "hello",
myProperty2: "world"
};
}
myOuterFunction();
Suppose I have a variable that contains the name of a function I want to run, I can run it by using window, like so;
var func = "myFunc",
myFunc = function(){ ... };
window[func](); // run the function in the func var
However, this doesn't work if the intended function is deep inside an object;
var obj = {
foo: {
hey: function(){ ... }
}
};
obj.foo.hey(); // this runs
var func = "obj.foo.hey";
window[func](); // this doesn't
I could use eval(), but I wonder if it's possible to avoid that, so as to not introduce the many security considerations that eval() comes with.
How can I run a function specified in a variable, when the function is in an object as described above?
You could iterate the splitted func and return the result of an walked object.
function getValue(object, path) {
return path.split('.').reduce(function (o, k) {
return (o || {})[k];
}, object);
}
var obj = { foo: { hey: function () { console.log('hey'); } } },
func = "obj.foo.hey";
getValue(window, func)();
(getValue(window, 'bar') || function () {})(); // default function, prevent exception
You can's pass nested properties under a single string. It must be done dynamically like.
var obj = {
foo: {
hey: function(){console.log("i run")}
}
};
obj.foo.hey(); // this runs
var route = ["obj","foo","hey"],
func = route.reduce((f,r) => f[r], window);
func()
I fully realize that this code is kinda strange by the very nature of javascript, but look at it:
var arr = [
function () {
this.b = "hello";
//or var b = "hello";
arr[1]();
},
function () {
var str = RealtimeParentFunc.b;
alert(str);
// want to get "hello"
}
];
// want to get "hello"!
arr[0]();
Maybe it's impossible, but I wonder if there's a way of doing this. How to get a variable of an array's function that called a function in the same array?
UPDATE
I had to go back to this problem and decided to post an update: of course I can't reference arr[i] from within itself, but I must emphasize that the code above was not supposed to be taken too literally: it was just a demo of what I wanted; but it looks like I can do what I want if I have a small "adjuvant" function that is previously defined in the code:
var a = function (i, v) {
return arr[i]()[v];
};
var arr = [
function () {
var h = "hello, ";
var n = a(2, "n");
return {
"h": h+n
}
}, function () {
var h = a(0, "h");
alert(h)
}, function () {
return {
"n": "your name"
}
}];
arr[1]();
You can't define an array and access it's values at the same time, since at the time of creation, the arr2 does not exist yet.
The [ function(){ .. }, function(){ .. }] array isn't created and set to arr2 until it reaches the ; semicolon at the end. Therefore you can't reference arr2[1]() while it's being defined.
On that note, what you can do is define the array first, then .push() the functions into it, but you're still limited to doing it sequentially:
var arr2 = [];
arr2.push(
function () {
var b = "hello";
//arr2[1](); // CAN'T DO THIS since arr2[1] doesn't exist
return {
b: b
};
});
arr2.push(
function () {
var str = arr2[0]().b;
alert(str);
// want to get "hello"
});
// want to get "hello"!
arr2[0]();
arr2[1]();
See working fiddle: http://jsfiddle.net/amyamy86/5k57X/
I have created a Javascript namespace like so:
var MyApp = function() {
return {
someFunction : function(x) {}
alert(MyApp.y);
}
}();
This allows me to do this:
MyApp.someFunction(x);
I would like to be able to do the following:
MyApp.y = "test" so that my someFunction can access this variable Y.
Any ideas on how to solve this? I'd like to keep my NS syntax intact so a solution that works with my example code would be nice.
What you described should work. (Except you have a syntax error and an unused argument x.)
var MyApp = function() {
return {
someFunction : function(x) {
alert(MyApp.y);
}
}
}();
MyApp.y = 'test';
MyApp.someFunction() // alerts 'test'
Another approach is to treat your outer function more like a constructor and pass y as a closure:
var MyApp = (function (y) {
return {
y: y,
someFunction: function () {
alert(MyApp.y); // or alert(this.y)
}
}
} ('test'));
MyApp.someFunction(); // alerts 'test'
I would go with something like this:
var MyApp = function() {
var _y = "default value";
return {
someFunction: function(x) {
console.log(_y);
},
setY: function (y) {
_y = y;
}
}
}();
This will mean that it is safe to call MyApp.someFunction() before assigning a value to y. It also means that the contents of the variable is maintained within the namespace's scope, e.g.
console.log(MyApp._y); // undefined
Here would be how to use it:
MyApp.someFunction(); // "default value"
MyApp.setY("new value");
MyApp.someFunction(); // "new value"
i am a little confused. i want to create a javascript object like:
function myObject(){
this.keyOne=1;
this.keyTwo=2;
this.keyThree=3;
function add(){
return this.keyOne+this.keyTwo+this.keyThree;
}
return{
add: add
}
}
so creating this object with
var newObject = new myObject();
is working fine and all attributes are correct. but with
var result = newObject.add;
all keys are suddenly undefined! i have no idea why? :/
You're not defining add() in a way that's exposed, you could do this for example:
function myObject(){
this.keyOne=1;
this.keyTwo=2;
this.keyThree=3;
this.add = function(){
return this.keyOne+this.keyTwo+this.keyThree;
}
}
var newObject = new myObject();
var result = newObject.add();
You can test it here.
Also note that you need to call add() with parenthesis, since it's a function, or you'll get the function itself back, not the result.
There currently is no meaning for the keyword public in standard JavaScript.
Based on your original code snippet, I suspect you meant:
function myObject(){
this.keyOne=1;
this.keyTwo=2;
this.keyThree=3;
function add(){
return this.keyOne+this.keyTwo+this.keyThree;
}
return {
add: add
};
}
The function would then return an object that only has one property: the add function. That object is created by the object literal after the return keyword.
But then there is no point using this. You could have written:
function myObject() {
var keyOne=1;
var keyTwo=2;
var keyThree=3;
function add() {
return keyOne + keyTwo + keyThree;
}
return {
add: add
};
}
Or even more succinctly:
function myObject() {
var keyOne=1;
var keyTwo=2;
var keyThree=3;
return {
add: function() {
return keyOne + keyTwo + keyThree;
}
};
}
This has the added advantage that you don't need to call it prefixed with new. It's just an ordinary function that creates and returns an object which contains another function:
var o = myObject();
alert(o.add());
You could allow the caller to specify the numbers to be added, like this:
function myObject(keyOne, keyTwo, keyThree) {
return {
add: function() {
return keyOne + keyTwo + keyThree;
}
};
}
var o = myObject(5, 4, 7);
alert(o.add());