I've made a function "ADD" which modifies the value of a variable :
function ADD(xs, n)
{
var nom_variable = xs;
var XS = eval(xs);
nouvelle_valeur = eval(nom_variable + "=XS+n");
}
var x = 5 ;
ADD("x",5); // now x = 10
I would like that the first argument of the function ADD is x, not "x". Is this possible ?
I want my students to write algorithms in a way similar to natural language.
Thanks !
You can't pass x as if it were a reference, but you could construct a functional reference (or Lens) although you are still not passing x but a variable that is a reference of x.
var x = 5;
var xRef = {
get : function(){
return x;
},
set : function(val){
x = val;
}
}
function add(ref, n){
var oldVal = ref.get();
ref.set(oldVal+n);
}
add(xRef, 5);
console.log(x);
It's definitely not pretty though.
Related
The function reverseArrayInPlace(array) is as per solution in eloquentJS. The reverseArrayInPlace function works, by altering the arrayValue as expected. A similar function written for a single variable does not work as expected. In the code, x should come out as 25, but comes out as 20.
//function from eloquentJS solutions, working as expected
`` function reverseArrayInPlace(array) {
for (let i = 0; i < Math.floor(array.length / 2); i++) {
let old = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = old;
}
return array;
}
let arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// working as expected, returns → [5, 4, 3, 2, 1]
// Writing similar function for a single variable
function changeInPlace(a) {
a += 5;
return a;
}
let x = 20;
changeInPlace(x);
console.log(x);
// Not working as expected returns, 20 instead of 25
`
Snippet of the code
Assign changeInPlace to a variable at second last line, and then print that variable in console. It should work.
The problem is that you are returning your calculated variable and not logging it. The one you are logging remains 20.
You must use your function as below :
let variable = changeInPlace(x)
Full code must be like :
function changeInPlace(a) {
a += 5;
return a;
}
let x = 20;
x = changeInPlace(x);
console.log(x);
// x should come out as 25
If for any reason you want to edit a variable value directly, you must access it globally like this:
function changeInPlace() {
x += 5;
return x;
}
let x = 20;
changeInPlace(x);
console.log(x);
For each time you want to change the value in a variable, it needs to be called out again in the form of a declaration. Therefore, output of your function needs to be declared as new value for variable x. Like below:
Your function
// Writing similar function for a single variable
function changeInPlace(a) {
a += 5;
return a;
}
let x = 20;
changeInPlace(x);
console.log(x);
// x should come out as 25
Mine
// Writing similar function for a single variable
function changeInPlace(a) {
return a += 5; // Made a small tweak to your function,
}
let x = 20;
x = changeInPlace(x); // this stores the output of the function in the same variable
console.log(x);
This should give you the desired output, assume this is what you've been asking for if otherwise let me know
Answered by Marijn (author of eloquentJS):
You can't change numbers in JavaScript, only create new ones, so there's no way for a function to change the value of a binding whose value is passes as argument to that function. See for example this section in the book: https://eloquentjavascript.net/04_data.html#h_C3n45IkMhg
I'm a JS dev, experimenting with functional programming ideas, and I'm wondering if there's anyway to use chains for synchronous functions in the way the promise chains are written.
For example:
function square (num) {
return num * num;
}
let foo = 2
let a = square(foo) //=> 4
let b = square(square(foo)) //=> 16
Fair enough, but what I'd like to do (often to make code parsing easier) is to chain together those methods by passing that in as the first parameter of a chain. So that something like this would work:
let c = square(foo)
.square()
.square() //=> 256
Is there any way to do this with vanilla javascript, or is this something I'd have to modify the Function.prototype to do?
You might be interested in the Identity functor – it allows you to lift any function to operate on the Identity's value – eg, square and mult below. You get a chainable interface without having to touch native prototypes ^_^
const Identity = x => ({
runIdentity: x,
map: f => Identity(f(x))
})
const square = x => x * x
const mult = x => y => x * y
let result = Identity(2)
.map(square)
.map(square)
.map(square)
.map(mult(1000))
.runIdentity
console.log(result)
// 256000
It is really a bad idea to modify Function.prototype or Number.prototype because you will pollute the default JavaScript objects, say: what if other framework also do the evil and add their own square?
The recommended way is to make an object by your self.
function num(v) {
this.v = v;
this.val = function() { return this.v; };
this.square = function() { this.v = this.v * this.v; return this; };
//and you can add more methods here
this.sqrt = function() { this.v = Math.sqrt(this.v); return this; };
return this;
}
var n = new num(2)
console.log(n.square().square().sqrt().val());
You wouldn't have to modify Function.prototype, but Number.prototype. You're trying to create a new method that acts on a number, not on a function. This does what you're trying to do:
Number.prototype.square = function() {
return this * this;
}
let x = 4;
let y = x.square().square(); // -> 256
You can set square and num as a property of square call`
function square (num) {
if (!this.square) {
this.square = square;
this.num = num || 0;
};
if (num === undefined) {
this.num *= this.num
}
else if (!isNaN(num)) {
this.num *= num;
};
return this;
}
let foo = 2;
let c = new square(foo).square().square();
console.log(c.num);
I have a question about how javascript stores functions internally.
Given this code:
var makesomething = function (x) {
var thing = {
x: x
};
thing.do = function () {
this.x++;
};
return thing;
};
var x1 = makesomething(1);
var x2 = makesomething(2);
Since I called the makesomething function twice, does that mean that there are essentially two copies of the "do" function or do the objects have reference to the same function but get called with different closure?
There are two copies, one created each time you called makesomething().
You'll notice that x1.do === x2.do is false.
If instead you do this:
var doIt = function() {
this.x++;
};
var makesomething = function (x) {
var thing = {
x: x
};
thing.do = doIt;
return thing;
};
var x1 = makesomething(1);
var x2 = makesomething(2);
Then both refer to the same function, and x1.do === x2.do will be true.
So I have a function that is recursive for inverting colors. Here is the code:
function invert(id,what){
var color = $(id).css(what);
var matchColors = /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/;
var match = matchColors.exec(color);
var r = (255 - match[1]).toString() + ",";
var g = (255 - match[2]).toString() + ",";
var b = (255 - match[3]).toString();
answer = 'rgb(' + r + g + b + ')' ;
$(id).css(what,answer);
};
So essentially I have a function that can be called in many instances (clicks of specific ids, hover on specific classes, etc.) and I do not know them all. But I need to know every single time this function gets called. How can I have an outside line of code that sets a variable equal to the amount of times the function has been called?
Wrap your function.
var wrapped = (function wrapper(present) {
function wrapping() {
++wrapping.count; // increment invocation count
return present.apply(this, arguments);
}
wrapping.count = 0; // counter, avaliable from outside too
return wrapping;
}(invert));
If you need to call it invert too, re-assign invert after.
invert = wrapped;
invert.count; // 0
invert();
invert.count; // 1
invert();
invert.count; // 2
I am not sure what your exact scenario is, but maybe you could override the function with a wrapper:
var invertOriginal = invert;
var counter = 0;
var invert = function(id, what, max) {
invertOriginal(id, what, max);
// do counter stuff here, e.g.
counter++;
};
I am trying to override the console in Nodejs with Winston.
for (var z in loggerSettings) {
console[z] = (function () {
var i = z + ''
, _backup = console[z];
return function () {
var utfs = arguments.length >= 2 ? util.format.apply(util, arguments) : arguments[0]
, coldex = 0;
if (true) logger[i == 'log' ? 'info' : i](utfs);
if (loggerSettings[i].console){
if ((coldex = utfs.indexOf(']') + 1) <= MAX_TAG_LENGTH)
_backup(utfs.substring(0, coldex)[i]['inverse'] + utfs.substring(coldex));
else _backup(utfs);
}
}
})();
}
Here var z is just a the basic console.log, console.info, console.warn methods. The issue is z is changing for each of the anonymous function. It is a bit challenging to address the problem, but the scope of z seems to change and the variable z is not exactly sticking to a constant value for each iteration of the loop. Z doesn't want to stick to its scope.
Javascript has function scope, but no block scope, meaning that every reference to z in your console-functions will use the last value of z.
If you want 'z' to stick, pass it as an argument to an anonymous function:
for (var z in loggerSettings) {
(function(z) {
console[z] = (function () {...});
)(z);
};