I would like to create a re-usable function that changes the boolean value of the variable that is passed in.
My example is below however this doesn't work as the first part of the statement 'item' is not assigned to the variable passed in.
let editable = true;
function toggleEditMode (item){
item = !item;
}
toggleEditMode(editable);
Any help?
You have to learn how js passes function arguments. It is passing by value here. Read this by value vs reference
Basically you can't pass by reference like you are trying to. You can make an object and then change a property on that object inside your function and it will work how you are expecting.
var i = { a:true }
function c(o){
o.a = !o.a
}
c(i)
console.log(i);
Related
I found that there are these two ways that a variable property value can be updated on a function call
Example 1:
function bar( arg ) {
return arg + 1;
}
var foo = {
num: 1
};
foo.num = bar( foo.num );
console.log( foo.num );
Example 2:
function bar( arg ) {
arg.num = arg.num + 1;
}
var foo = {
num: 1
};
bar( foo );
console.log( foo.num );
I want to know what are the proper naming convention for each of the method calls.
Also can anyone explain, how it is possible to update the original variable value inside a closed function operation as shown in example 2?
Primitive parameters (such as a number) are passed to functions by
value; the value is passed to the function, but if the function
changes the value of the parameter, this change is not reflected
globally or in the calling function.
If you pass an object (i.e. a non-primitive value, such as Array or a
user-defined object) as a parameter and the function changes the
object's properties, that change is visible outside the function.
Source : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
Well in javascript objects are passed by reference so when you pass a object to a function you're passing it's memory reference not a copy.
So when you update value in the function it updates the value at reference.
function bar(arg) {
arg.num = arg.num + 1;
}
var foo = {
num: 1
};
bar(foo);
console.log(foo.num);
When you pass a primitive value it is passed by value. It passes a copy of value so whatever changes you do in close function will not affect the original value.
function bar(arg) {
arg = arg + 1;
}
var foo = 1
bar(foo);
console.log(foo);
I want to know what are the proper naming convention for each of the methods.
There are no naming conventions for functions (I would only call them methods if they are directly associated to an object), except thar the name is camelCase. However there is a convention in functional programming that functions that return something are pure (they do not change anything, but just return something new, like your first function), and functions that return nothing are impure, they change something. Wether you strictly follow that pattern depends on your codingstyle, I follow that often but not always. It is also a bit harder in JS as JS is not typed.
also can anyone explain, how it is possible to update the original variable value inside a closed function operation as shown in example 2?
It is impossible. If you pass a number, it is passed as a value, you have no way to find out where that number belongs to. Thats a good thing as you can always keep track which function is able to mutate an object. bar(foo) is, bar(foo.num) is not.
I'm trying to set an object value to a function call using another value (array) as its parameter, however, for some reason the value comes back as undefined, I'm then trying access that value right after that. It's inside an IIFE.
I am unsure why this is happening because to the best of my knowledge the scoping is okay and the value should be initialized and executed by that time?
Here's a simplified example:
(function(){
var minefield = [1,2,3,'M',4,5,6];
function findMachine(minefieldMachine) {
return minefieldMachine === 'M';
}
var terrain = {
start:{initialMachienLocation:minefield.findIndex(findMachine)},
currentMutable:{mutableIndex:terrain.start.initialMachineLocation}//Error: "Uncaught type error cannot read property 'start' of undefined"
//Why isn't the above accessing the value declared in terrain.start.initialMachineLocation through the function call?
}
}());
However, doing this works, out of context from above:
function findMachine(minefield){return minefield === 'M'}
[1,2,3,'M',4,5,6].findIndex(findMachine);
//above returns the proper index value, 3.
This has nothing to do with the function.
What you are attempting to do is, essentially, this:
var foo = {
a: 1,
b: foo.a
}
You need to consider the order of operations.
The object literal constructs an object which is then assigned to the variable foo.
… except that while the object is being constructed, you are trying to read the value of foo. It doesn't have one yet, so this fails.
You need to do this in two steps.
var foo = {
a: 1,
}
foo.b = foo.a;
There is a way (in angularJS) to pass by reference a variable in the scope in a function (to modify it)?
I've tried but the variable change doesn't happen.
Here my code
$scope.modifyVar = function (myVariable){
myVariable = 92;
}
$scope.modifyVar($scope.txtNumberOfChuck);
You cannot pass a variable by reference in Javascript. However you can pass the complete object and get your values changed.
In your case you can pass the $scope object and then modify the property value. Something like this:
$scope.modifyVar = function (myObj){
myObj.txtNumberOfChuck = 92;
}
$scope.modifyVar($scope);
I am trying to change myprop's value with option 3 and 4, but with no success. Why?
object1 = {myprop:"value1", ....};
button1.addEventListener('click', function(e){
object1.myMethod("value2"); // 1) working. myMethod is a method that sets myprop's value
object1.myprop="value2"; // 2) working
myFunction1(object1.myMethod); // 3) not working
myFunction2(object1.myprop); // 4) not working
});
function myFunction1(src) {
src("value2");
}
function myFunction2(src) {
src="value2";
}
You are passing the value of object1.myMethod/object.myprop which gets copied to the src variable.
You then either call the function (but in a different context so the value of this inside it is different) or overwrite the value of src while leaving the original property alone.
If you want the function to be called in the right context, you need to pass that context in with call() or apply().
If you want to overwrite the myprop property of the object stored in object1 then you have to have a reference to the value of object1 and set the property on that.
When you define your anonymous function to handle the click event (button1.addEventListener('click', function(e) {...}), the value of object1.myMethod and object1.myprop are captured in the closure.
What it means is: you are defining a function, and this function, when executed, will need some values that are in scope when it was defined, but not when it will be executed (both object1.myMethod and object1.myprop). The function is being defined right there in your code, but is being passed around as a parameter and will be called far away from there, whenever the click event happen on the button.
What happens is that that object1.myMethod and object1.myprop are evaluated to its values and captured in the function's closure, to be available later when the function will be executed (you don't see any of this happening, it just happens).
So, your approach won't work here. I see one alternative for setting the property, that is pass the object in which you want to change the value, and pass the name of the property that you want to change.
// 1 way to make the property call work
object1 = {myProp:"value1"};
button1.addEventListener('click', function(e){
myFunction2(object1, 'myProp');
});
function myFunction2(src, prop) {
src[prop]="value3";
};
For the methods parts, I can see 3 ways to make it work (actually 4, if I've used apply instead of call).
First is the same as in the case of the property: you pass the object1 and the name of the slot where is the function.
Second, you can pass the object1 and the function, and later call your function in the context of object1.
Third, you can create, from your object1.myMethod, a new function that will be bound to object1 (that is, object1 will be its context), no matter where you will call it later. That is done with bind.
Examples:
// 3 ways to make the method call work
object1 = {myMethod:function(someParam){console.log(someParam)}};
button1.addEventListener('click', function(e){
myFunction1(object1, 'myMethod');
myFunction3(object1, object1.myMethod);
myFunction4(object1.myMethod.bind(object1, 'value3'));
});
function myFunction1(src, prop) {
src[prop]("value3");
};
function myFunction3(src, method) {
method.call(src, 'value3');
};
function myFunction4(func) {
func();
};
Quick question on Javascript to which I can't find a clear concise answer.
I'm building an app that's way ahead of anything I've done before and involves multiple classes being instantiated. These objects are then passed into a processing class that checks user inputs, draws onto canvas and updates the objects that it has been passed.
I am wondering, how does JavaScript handle passing objects to functions? Am I passing a copy of the object, or am I passing a reference to the object?
So if my controller class alters one of the objects variables, is that changed everywhere or just in the object that that controller sees?
Sorry for such a simple, possibly easily testable question but I'm not even sure if I'm making a class correctly at this point thanks to errors piling up.
When passing in a primitive type variable like a string or a number, the value is passed in by value. This means that any changes to that variable while in the function are completely separate from anything that happens outside the function.
function myfunction(x)
{
// x is equal to 4
x = 5;
// x is now equal to 5
}
var x = 4;
alert(x); // x is equal to 4
myfunction(x);
alert(x); // x is still equal to 4
Passing in an object, however, passes it in by reference. In this case, any property of that object is accessible within the function
function myobject()
{
this.value = 5;
}
var o = new myobject();
alert(o.value); // o.value = 5
function objectchanger(fnc)
{
fnc.value = 6;
}
objectchanger(o);
alert(o.value); // o.value is now equal to 6
As well described in https://stackoverflow.com/a/5314911/636348, in JavaScript it's always pass by value, but for objects the value of the variable is a reference.
So, it's not a pure pass by reference. Here's an example to understand this concept:
E.g.:
x = {member:"foo"}
If you change the object with another object inside a function, you won't get the new object outside the function scope because you just create another object. The original reference is still bound to the original object:
function changeObject(x) {
x = {member:"bar"};
}
changeObject(x);
alert(x.member)
output: foo
instead, if you alter a member inside a function, the object will be changed:
function changeMember(x) {
x.member = "bar";
}
changeMember(x);
alert(x.member)
output: bar
If you pass in a variable which is pointing to an object, it passes a reference to the object. If you pass in an object literal, then obviously no other class or function will be able to change that object.