Is a wrapper function syntax invalid in JavaScript? - javascript

In this article, the replier offers a correct and well structured solution to a problem.
However, he also argues that the suggested approach (i.e. making a wrapper for a callback function) isn't a valid JavaScript. That begs three questions.
Is that so?
What bad things can happen if applied?
What would be a valid JavaScript to resolve that issue?

The ... is not valid syntax. There are two solutions:
First, you could manually list out a lot of parameters:
callback: function (jq1, jq2, jq3, jq4, jq5, jq6) {
return pageselectCallback(your1, your2, jq1, jq2, jq3, jq4, jq5, jq6);
}
This of course won't work if there are more than six parameters. To fix this, you can use the .apply method, which takes an array of parameters:
callback: function () {
return pageselectCallback.apply(null,
Array.prototype.concat.call([your1, your2], arguments));
}

The example code in the answer is not valid. (, ...,)
But the solution is valid.

Related

"use strict" and naming arguments in function calls

A colleague advised me to add "use strict"; to the top of my JS code to highlight any gaps in my definitions and potential reference errors, etc. I am very happy with it because it has identified several pieces of code which might have been a problem down the line.
However, another colleague advised me that when calling functions which take multiple arguments, it can be helpful to name the arguments as they are specified, especially if it's something like a bunch of booleans. To illustrate, here's a couple of function calls:
logData(data, target, preserveLog=true, changeClass=false, wrapLine=false);
...is a whole lot clearer than:
logData(data, target, true, false, false);
But "use strict"; hates this. everywhere I've done this, I get a reference error in the console. It still runs fine, as would be expected, but the console is now cluttered with all these apparently non-defined references.
Does anyone know if there's a way around this so that I can keep my coding conventions which my colleagues appreciate, or am I going to have to either stop using "use strict"; or go through all my code and remove the names of arguments?
Thanks.
However, another colleague advised me that when calling functions which take multiple arguments, it can be helpful to name the arguments as they are specified, especially if it's something like a bunch of booleans.
This is terrible advice!
Javascript doesn't actually support passing arguments by name this way. Each of the arguments you pass "by name" is actually being treated as an assignment to a global variable with that name, and "use strict" is correctly identifying this as an error.
If you want to be more clear about what values you're passing, assign the values to real local variables and pass those, e.g.
var preserveLog = true;
var changeClass = false;
var wrapLine = false;
logData(data, target, preserveLog, changeClass, wrapLine);
If you really wanted to keep using your original pattern, you could even assign to those variables in the function call, so long as you declare them as local variables first:
var preserveLog, changeClass, wrapLine;
logData(data, target, preserveLog=true, changeClass=false, wrapLine=false);
(With a hat-tip to dav_i for this answer, which I based my recommendation off of.)
Duskwuff has already provided an excellent answer and I won't add anything to that, other than to say I fully agree with it, but he didn't mention any conventions that arose due to ES6.
In ES6, you still don't have named parameters, but you have the next best thing, which is Object destructuring assignment.
This allows us to pass what appears to be named parameters, but are really just destructured object properties of an object that is never directly used.
In the context of the example you provided, it would look something like this:
logData({data, target, preserveLog:true, changeClass:false, wrapLine:false});
Where the function is defined as:
function logData({data, target, preserveLog, changeClass, wrapLine}) { ... }
I've seen a lot of libraries that prefer this calling convention where ES6 is available, and it's very convenient too because the order of the parameters is also no longer important.

Why can't I skip parameter assignments in a function signature?

With array destructuring, it's possible to discard leading items by inserting commas without a preceding reference:
const [ , two ] = [ 1, 2 ]
The same isn't true of function signatures — the following code won't parse because the leading comma in the signature is unexpected:
function ditchFirstArgument( , second ){}
Why do I need to provide references for leading parameters in ES6 function expressions?
Roman's insight from Go is useful but inappropriate to JS where the token _ is a valid reference, conventionally used by the Underscore and later Lodash libraries.
Even if that's acceptable, you'd have to create and avoid dud references for every unused argument, which isn't ideal.
However, it is possible to destructure a function argument into an empty object, which effectively nullifies the parameter without reference.
function take_third( {}, {}, third ){
return third
}
EDIT: As Paul points out in the comments, this will throw if any of the skipped parameter values are null or undefined. undefined values can be guarded against with default assignments, but this won't work for null:
function take_third( {} = {}, {} = {}, third ){
return third
}
Why do I need to provide references for leading parameters in ES6 function expressions?
Because otherwise it would be a syntax error. In not just ES6 but any version of the language you cannot elide formal parameters because the spec does not provide for it.
If you really want to do this (but why?), you could write it as
function ditchFirstArgument(...[, second]) {}
or at least you will be able to in some future version of ES; see https://github.com/tc39/ecma262/commit/d322357e6be95bc4bd3e03f5944a736aac55fa50. This already seems to be supported in Chrome. Meanwhile, the best you can do is
function ditchFirstArgument(...args) {
const [, second] = args;
But why does the spec not allow elision of parameters?
You'd have to ask the people who wrote it, but they may have never even considered it, or if they did, rejected it because it's bug-prone, hardly ever necessary, and can easily be worked around using dummy formal parameters like _.
I believe it's a common pattern to name unused variables with an underscore:
function ditchFirstArgument(_, second) { /* ... */ }
While it would not prevent you from actually using this variable (like in Go), it seems to be a pretty straightforward workaround.

Nested call to function in Javascript

Intellij IDEA shows a warning when ever I write Javascript like this:
someFunction(someOtherFunction());
But the explanation is not really helpful:
"This inspection reports any Javascript function calls used as
arguments to another function call."
This is something I do frequently, so what's the potential trap hiding there worth warning of? Or if it's just some coding convention, what's the reason for it?
It is a warning because most of the time, you want to pass a function reference as an argument. It is mostly used as a callback:
someFunction(someOtherFunction);
function someFunction(fn){
fn.call();
}
In that example, someOtherFunction() instead of someOtherFunction would not work as expect (unless someOtherFunction returns a function itself).
someFunction(someOtherFunction()); work more like a getter.
someFunction(someOtherFunction());
function someFunction(int){
alert(int === 1);//True;
}
function someOtherFunction(){
return 1;
}
It gives a warning because it is a common mistake for new developers.

Extensions of Javascript function shorthand

I know it's possible to define a function this way:
x=y=>y*y
which corresponds to:
function x(y){ return y*y; }
But I was wondering, is it possible to extend this to two or more arguments?
i.e. x=y,z=>y+z or similar to correspond to function x(y,z){ return y*z; }
Is there a similar convention to the very first example that allows for two or more arguments? I know that the x=y,z=>y+z syntax isn't right as I get errors regarding the definitions of at least one of variables... So how can it be done, or rather... can it be done??
yes try
x=(z,y)=>z*y
haha :D
http://jsfiddle.net/FaSv2/

Method implementation difference.. need some understadning

Excuse me first. because i don't know this is question is valid or not. i if any one clear my doubt then i am happy.
Basically : what is the different between calling a method like:
object.methodname();
$('#element').methodname();
calling both way is working, but what is the different between, in which criteria make first and second type of methods. is it available in the core javascript as well?
In case if i have a function is it possible to make 2 type of method call always?
Can any one give some good reference to understand correctly?
Thanks in advance.
The first syntax:
object.methodName();
Says to call a function, methodName(), that is defined as a property of object.
The second syntax:
$('#element').methodname();
Says to call a function called $() which (in order for this to work) must return an object and then call methodname() on that returned object.
You said that "calling both way is working," - so presumably you've got some code something like this:
var myObject = $('#element');
myObject.methodname();
This concept of storing the result of the $() function in a variable is commonly called "caching" the jQuery object, and is more efficient if you plan to call a lot of methods on that object because every time you call the jQuery $() function it creates another jQuery object.
"Is it available in the core javascript as well?" Yes, if you implement functions that return objects. That is, JS supports this (it would have to, since jQuery is just a JS library) but it doesn't happen automatically, you have to write appropriate function code. For example:
function getObject() {
return {
myMethod1 : function() { alert("myMethod1"); return this; },
myMethod2 : function() { alert("myMethod2"); return this; }
};
}
getObject().myMethod1().myMethod2();
In my opinion explaining this concept in more depth is beyond the scope of a Stack Overflow answer - you need to read some JavaScript tutorials. MDN's Working With Objects article is a good place to start once you have learned the JS fundamentals (it could be argued that working with objects is a JS fundamental, but obviously I mean even more fundamental stuff than that).
The difference is very subtle.
object.methodname();
This is when JavaScript has the object at hand.
$('#element').methodname();
If you are using jQuery, you are asking jQuery to select the object that has the id of #element. After that you invoke the method on the selected object.

Categories