I do not understand the function [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I do not understand the function fromToFn(),
in my example there is no function with that name,
I do not understand my example
Example:
var fromTo = function fromTo(i,limit){
return function(){
var next = i;
if(i<limit){
i += 1;
return next;
}
return undefined;
}
}
var collect = function collect(fromToFn,array){
return function (){
var value = fromToFn();
if (value !== undefined){
array.push(value);
}
return value;
}
}
var array = [];
var col = collect(fromTo(0,2),array);
col(); //returns 0
col(); //returns 1
col(); //returns undefined
console.log(array); //returns [0,1]

I do not understand the function fromToFn(), in my example there is no function with that name
That's true, but it doesn't matter. Functions are first-class objects in JavaScript, references to them can be passed around in variables, properties, and parameters.
fromToFn is the name of a parameter in the collect function:
var collect = function collect(fromToFn,array){
// ----------------------------^
So if we pass a function into collect, we can use it within collect via that parameter.
The code does pass a function into collect, here:
var col = collect(fromTo(0,2),array);
...because fromTo(0, 2) returns a function, which is then passed into collect. To be very clear, because there are a couple of things going on, the function being passed into collect is not fromTo, it's the function fromTo returns. That line can be written:
var functionToPassToCollect = fromTo(0,2);
var col = collect(functionToPassToCollect,array);
Here's a simpler example demonstrating using a parameter to call a function passed in:
function example(f) {
f();
}
function callMe() {
console.log("callMe was called");
}
example(callMe);

When you do
var col = collect(fromTo(0,2),array);
You're calling the collect function and the first argument you pass is fromTo(0,2).
The fromTo function, when called, returns a function. So fromToFn, in the call to collect, is a function and can be called too:
var value = fromToFn();
fromTo and collect handle functions, they're called "higher-order" functions. This is possible in JavaScript because in JavaScript functions are first-class values, they can be assigned to variables like other types of values (see First-Class functions).
In this specific case, the point of the function returned by fromTo is that it can uses the variables of the fromTo scope, it's called a closure.

fromToFn is the function that sent to the 'collect' function as parameter :
function collect(fromToFn,array);
and you send the fromTo function :
collect(fromTo(0,2),array)

Related

Functions returning functions understanding why it works [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 2 years ago.
function retirement(retirementAge) {
var a = ' years left until retirement.';
return function(yearOfBirth) {
var age = 2016 - yearOfBirth;
console.log((retirementAge - age) + a);
}
}
var retirementUS = retirement(66);
retirementUS(1990);
My question is why yearOfBirth can be equal to retirementUS
I understand this works I just don't understand why.
the return value of retirement is a function.
Since functions are „First-class citizens” in JavaScript, you can assign a function to a variable (or return it from another function).
You assign the return value to a variable retirementUS. This variable now holds a reference to the anonymous function function(yearOfBirth).
In the last line, you pass an argument into that anonymous function.
Within that one, the argument gets referenced as yearOfBirth.
Since it is within the same scope as retirement, it has access to retirementAge.
Does that answer your question?
In JavaScript functions are first-class citizens, you can assign a function to a variable.
You retirement function is returning another function that you are assigning it to a variable you called retirementUS.
In your line:
var retirementUS = retirement(66);
You returned the result of the first function that took retirementAge as parameter and returned another anonymous function.
Then you called that anonymous function that you assigned to retirementUS:
retirementUS(1990);
You could also call both functions directly by:
retirement(66)(1990)
function retirement(retirementAge) {
var a = ' years left until retirement.';
return function(yearOfBirth) {
var age = 2016 - yearOfBirth;
console.log((retirementAge - age) + a);
}
}
const retirementUS = retirement(60);
// your "retirement" returns another function
console.log(`Type of "retirementUS" is: ${typeof retirementUS}`)
// so you need to call that second function with its yearOfBirth parameter:
retirementUS(1990)

How to get context of the object that calls a method? 'This' doesn't work. JS [duplicate]

This question already has answers here:
ES6 arrow function and lexical scope inside a function [duplicate]
(2 answers)
Closed 4 years ago.
How can I get the reference to what's being return to the method call? Like how we have the arguments variable to get all arguments being passed to a function. How can I get what's being returned to so I can chain a function?
let myFunc = function(obj, num){
if (typeof obj === 'number' && typeof num === 'undefined') {
num = obj;
obj = this;
}
console.log(obj.name);
console.log(num);
console.log(Object(this));
return obj;
};
let myObj = {
name: 'Devin',
};
myFunc(myObj, 1);
myObj.myFunc = myFunc;
myObj.myFunc(2).myFunc(3);
edit: It's written out this because it's currently used in many places that I will have to refactor down the road but do not have time to right now. So I'm trying to do a few changes that don't affect current code but will work the way I want moving forward. myFunc(myObj, 1) is current but I have done a minor refactor to inline like so... myObj.myFunc(myObj, 2).myFunc(myObj, 3) ... but I thought I could remove myObj as an argument since it's being returned.
edit 2: Changed arrow es6 function to using function keyword to keep this context and added console.log(Object(this)). But still getting undefined from myObj.name and Object(this) only gives the argument
ANSWER: The problem was that I was using an arrow function and that I had typeof num === 'number' instead of equal to 'undefined'. Thank you.
myFunc.bind(myObj) doesn't serve any good purpose because arrows cannot be bound. In order to use dynamic this it should be regular function, e.g. shorthand syntax:
let myObj = {
name: 'Devin',
myFunc(num) {
console.log(num);
return this;
}
};
myObj.myFunc(2).myFunc(3); // basically a noop

why is one of these a closure and not the other one? Javascript [duplicate]

This question already has answers here:
Is it true that every function in JavaScript is a closure?
(2 answers)
Closed 7 years ago.
I have been reading about closure in JS and I wouldn't say I understand it perfectly but at least having some knowledge about it after reading a few examples and info from different sites but I can't really understand why one of these is a closure and not the other one.
Not closure function
var secret = "007";
function getSecret(){
var secret = "008";
function getValue(){
return secret;
}
return getValue();
}
getSecret();
Closure function
var secret = "007";
function getSecret(){
var secret = "008";
function getValue(){
return secret;
}
return getValue;
}
var getValueFun = getSecret();
getValueFun();
both of them has the same output as I can realize the first one that's not a closure returns the function invoked and the closure one just returns the function. This is the only difference I can think of and is this part of the reason why one of them is a closure and not the other one?
// You can try this:
var secret = "007";
function getSecret(){
var secret = "008";
var getValueFunc = function(){
return secret;
}
return {
getValue:getValueFunc
};
}
var getValueFun = new getSecret();
getValueFun.getValue();

Javascript Naming Convention: value() vs getValue() [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Imagine a simple object:
function createObj(someValue) {
return {
someFunction: function () {
return someValue;
}
};
};
It basically does:
var obj = createObj("something");
var result = obj.someFunction(); // "something"
Now, someFunction refers to a function that returns a value.
What should be the correct naming convention used in javascript for the someFunction function?
Should it be named as what it does? Or its ok to name it with the name of the object that it returns?
I mean, should I name it value(), or should I name it getValue()? Why?
Thanks in advance.
There's no "correct" naming in JavaScript. However, there are three conventions that are mostly used:
Independent getter and setter:
In this approach, we create both a getter and a setter functions, like in Java:
var value;
this.getValue = function () {
return value;
}
this.setValue(val) {
value = val;
}
Combined getter/setter method
In this approach, you have a single method that does both. The magic here is that it checks whether you provides a new value for your property:
var _value;
this.value = function (val) {
if (arguments.length > 0) {
// Acts like a setter
_value = value;
return this;
}
return _value;
}
It's also common to define your setter to return the actual instance of your class, so you can do this:
myObj
.setProp1("foo")
.setProp2("bar");
Object.defineProperty
This one is less used, but it's also an option. It's similar to Objective-C #property statement:
var _value;
Object.defineProperty(this, "value", {
get: function() {
return _value;
},
set: function(val) {
_value = val;
}
});
Then you can access it like if it was a public property:
console.log(myObj.value); // Calls the getter method
myObj.value = newValue; // Calls the setter method
General naming conventions say getValue() would be the name of a function, where value would be the name of the variable.
So, if you were accessing the data directly, you would use obj.value, whereas if you were using a function to get some data, you would use obj.getValue().
There are quite a few naming conventions out there for Javascript in particular.
This question has a sister and hopefully this will help with your question: Clicky for more info
I am personally a fan of getValue and setValue but when reading other peoples codebase, i have seen
object.value = function(item){
if (!item) return this.value;
this.value = item;
}
jQuery uses this on the regular, which is why i don't want to necessarily bash on it.

Javascript: Forwarding function calls that take variable number of arguments [duplicate]

This question already has answers here:
Passing arguments forward to another javascript function
(5 answers)
Closed 5 years ago.
I think I need something like ruby's splat * here.
function foo() {
var result = '';
for (var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
}
function bar() {
return foo(arguments) // this line doesn't work as I expect
}
bar(1, 2, 3);
I want this to return "123", but instead I get "[object Arguments]". Which makes sense, I suppose. It's passing the object that represents the arguments, but not the arguments individually.
So how do I simply forward any number of arguments to another function that takes any number of arguments?
UPDATE: Since ES6, you can use the spread syntax to call a function, applying the elements of an iterable object as argument values of the function call:
function bar() {
return foo(...arguments);
}
Note that you can also receive a variable number of arguments as a real array, instead of using the arguments object.
For example:
function sum(...args) { // args is an array
return args.reduce((total, num) => total + num)
}
function bar(...args) {
return sum(...args) // this just forwards the call spreading the argument values
}
console.log(bar(1, 2, 3)); // 6
In the days of ES3/ES5, to correctly pass the arguments to another function, you needed to use apply:
function bar() {
return foo.apply(null, arguments);
}
The apply method takes two parameters, the first is the thisObj, the value of it will be used as the this value inside the invoked function, if you use null or undefined, the this value inside the function will refer to the global object, in non-strict mode, otherwise is undefined.
The second argument that apply expects is an array-like object that contains the argument values to be applied to the function.
Check the above example here.
Try this return foo.apply(this,arguments). Also you can just use Array.prototype.slice.apply(arguments).join('') for your foo function.

Categories

Resources