I've noticed that when creating functions in Java Script ES5 you can specify parameters that will not necessarily have to be used, e.g.
function foo(uselessParam) {
// code that will not use uselessParam
}
If I'm correct - if I wont use this parameter within my function I can call that function without passing that parameter and "foo" will still run without throwing errors. This gave me idea to use fat arrows in ES6 like this:
let foo = f => {
// code not using f parameter
}
"f" in my opinion points that this piece of code is a function in more intuitive way than "()" I like doing so, even that "()" suppose to be used when no parameters are specified.
Here is my question: is there any scenario when using empty parameter instead of no parameters passed at all could be a problem? Could using this pattern cause any problems? What do you think?
The function will have a different .length, so if any introspective code is using that property for anything, you may see unexpected results.
Related
I am working on a certain assessment where I have to modify a code base to implement a feature. Now, there is a jsx file that calls a hook, and a js file in which the hook is defined. Let's call the jsx file thing.jsx, and let's say that it has some lines of code that look like this:
import useHook from '../hooks/useHook';
const thing = useHook({thingy1, thingy2, thingy3});
//rest of code goes here
Then, the file in which the hook is defined (useHook.js) looks like this:
function useHook() {
//I'm supposed to implement this function
}
export default useHook;
Now, notice that in the hook's definition, there are no parameters. Yet, in the jsx file, they pass in an object.
Since this is an assessment for me, there are certain things that they don't want me to change. I'm torn as to whether or not they are expecting me to leave the function definition with no parameters in it as shown above (which would imply that you can just simply pass in parameters to hooks that have no parameters in their definitions?), or if they are actually looking for me to add the parameters myself.
What do you think? Can you just pass parameters to a parameter-less hook in another file, or am I right to just add the parameters to the function myself?
React Hooks is javascript functions, and if you want to access the parameters of function you must use inside the hook, like this:
function useHook({thing1, thing2, thing3}) {
//I'm supposed to implement this function
}
Well, nothing wrong with passing parameters to a function that isn't expecting any. But it's just almost pointless.
Since this is essentially javascript, it will definitely allow you to pass the params.
So, to answer your questions,
Can you just pass parameters to a parameter-less hook in another file,
Yes, you can.
or am I right to just add the parameters to the function myself?
This depends on your requirement. It needs to be noted that formal parameters aren't the only way to access a function's parameters, it is futile to do so if the function does nothing with its arguments even after you pass them in.
Also, a small note for you, just in case it may help, do check out the arguments object. You could pass in the parameters, even without the function explicitly expecting them in the definition, and still use the parameters. Run the snippet below and see for yourself:
function testFunc() {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
testFunc(1, 2, 3);
why this kind of bad design is made on js? Is there any special reason to design the automatic semicolon insertion like this?
Here is my code, It is not work in js in chrome:
(function(){console.log("abc");})()
(function(){console.log("123");})();
Here is the error:
Uncaught TypeError: (intermediate value)(...) is not a function
I know the right version of this code is :
(function(){console.log("abc");})();
(function(){console.log("123");})();
I just want to know why js syntax is designed so stupid. History reason?
I also add this question as a warning to everybody try to use the automatic semicolon insertion of javascript, please just add ; everywhere it needs, the automatic semicolon insertion of javascript is rubbish. It does not work as your expect.
The exist answer is too complex to my case, so I ask a new one:
https://stackoverflow.com/a/2846298/1586797
Another looks good but not work case 2:
x=1
(function(){console.log("123");})()
The linked question's answers explain the spec's three rules for ASI, for example this one. tl;dr:
If it doesn't work, try with semicolon.
The program should end with a semicolon.
If a statement says "can't put newline here", punish it with semicolon.
Your code does not satisfy any of the criteria.
The first line could return a function, and if so that function should be allowed to be invoked; so ( that the second line begins with is not illegal
The first line is not the last line of the program
There is no restricted syntax here.
Therefore, no automatic semicolon for you.
Some people have thus claimed that while (f(){})() syntax is good IIFE syntax, it might be good to do !f(){}() instead:
!function(){console.log("abc");}()
!function(){console.log("123");}();
This works as intended because ! just negates the (discarded) result of the function application, and also because ! as purely unary operator is an illegal character to continue the first line (i.e. f(){}()! is not a thing). This triggers rule 1, and ASI can take place.
The counterargument is that it is butt-ugly (i.e. for anyone not already familiar with the practice, it takes a while for them to understand the purpose of ! in this idiom).
Your second example is similar in nature: as far as the JS parser is concerned, 1 is a value (the fact that it is an integer and could not possibly be a function is a bit lost to it). Look at this example that syntactically is completely equivalent to yours:
a=function(f) { console.log("A CALLED!"); return f; }
x=a
(function(){console.log("123");})()
# => A CALLED!
123
Here, a is a function, so it can be invoked with function(){console.log("123");} as an argument; it returns function(){console.log("123");} unchanged after printing to the console; then () invokes that return value, and 123 is printed as well. Everything works. Thus, Rule #1 is not triggered, no semicolon for you.
(function(){console.log("abc");})()
(function(){console.log("123");})();
is equivalent to:
(function(){console.log("abc");})()(function(){console.log("123");})();
And is what is usually referred to as function currying.
For IIFEs (immediately invoked function expressions) you need to end with ;
For more on function currying see this post. Obviously your console log functions do not work as currying functions, but the syntax yourFunction(a)(b)(c) is a cool feature of the language that is used for currying.
Your code can be simplified as:
(function(){})()()();
This code will get same error.
The () expect a expression to call.
The first () call the (function(){}), the second () call the (function(){})()'s result, but the result is not a function, so it's wrong.
Without the semicolon those statements are chained. You call the first function and give the second func as argument to the return value of the first one. This could actually work, if the first function had a function as return value.
When you expand the code it becomes more obvious:
var a = function(){console.log("abc");};
var b = function(){console.log("123");}
(a)()
(b)();
the last two lines become:
(a)()(b)();
this is equivalent to
var x = a();
x(b);
since a does not return anything, it cannot call it as function with b as argument.
I think this will be clearer if you use this:
x=1
(function(){console.log("123");})()
The error states 1 is not a function. Makes it clear that (function...) is treated like the argument of a function call to 1:
x=1(function(){console.log("123");})()
Because ()() is self-invoking function and ();() are two differnt functions and interpreter is interpreting it accordingly.
Here two pieces of code are totally different for an interpreter.
(function(){console.log("abc");})()(function(){console.log("123");})();
and
(function(){console.log("abc");})();(function(){console.log("123");})();
however, this code will work fine
var a=12
var b=10
console.log(a+b)
Long answer sort :
(function(){console.log("abc");})()
is trying to immediately-invoke the preceding expression which is
(function(){console.log("123");})();
Which would be the return value of the preceding IIFE.
IIFEs can act differently in the missing semicolon situation. That is why we see code as follows:
;(function() {
console.log('abc');
})()
Please have a look of details description here : https://gist.github.com/khellang/8518964
I am used to seeing parameters being passed to functions within one set of parenthesis. I'm used to this from C# and also from starting to learn JavaScript.
Here is one example:
functionName(parameter1, parameter2, parameter3) {
code to be executed
}
But I came across this AngularJS example where using filters from the JavaScript code is done by passing parameters in a parenthesis of their own.
$scope.filteredText = $filter('uppercase')($scope.originalText);
I would expect the parameter to be passed as:
$scope.filteredText = $filter('uppercase', $scope.originalText);
Why it it passed in a parenthesis of its own instead? What kind of syntax is that? Is it JavaScript or is it AngularJS specific?
($scope.originalText) is not a second parameter to the $filter function.
The $filter('uppercase') function returns another function and you are passing $scope.originalText as a parameter to this returned function. It's just a shortened version of:
var f = $filter('uppercase');
f($scope.originalText);
I don't know how to phrase it properly so I can't find answers by Google, but here's basically my problem:
I want my CoffeeScript to output something like this in JS: (I'm developing a Node app)
var someapp = require('someapp')
var another = require('another')
someapp.configure(function() {
someapp.use(another.do('argument'));
});
So I wrote it this way in CoffeeScript:
someapp = require 'someapp'
another = require 'another'
someapp.configure () ->
someapp.use another.do 'argument'
But instead, I'm getting this output:
some.configure(function() {
return someapp.use(another["do"]('argument'));
});
Obviously, my biggest problem is the line return someapp.use(another["do"]('argument')); I can't find in the CoffeeScript docs or elsewhere the proper syntax, so I'm hoping someone can point me to the right direction. Thanks in advance.
According to the docs,
CoffeeScript provides the do keyword, which immediately invokes a passed function, forwarding any arguments.
So, coffeescript outputs another["do"] to avoid using the do reserved keyword.
Furthermore, in this case, the function another.do is an object property that happens to be a function. It can be accessed by using both another.do() and another["do"]().
I've been shown how to call variable javascript functions by using window[]().
Is it possible to call variable jQuery functions? If so, how?
Usually, I only need a ternary to flip a visible switch, and it would be very convenient to smush many lines of code into 1. For example, inside an $.aja() success:
if(msg.length > 0){
$("#gridViewContainer").slideDown()
}
else{
$("#gridViewContainer").slideUp()
}
This is probably a bad example since a boolean can probably be passed to slide() or something, but I'd like to use the concept in the linked question above.
This did not work for me:
$("#gridViewContainer")[((msg.length > 0)?'slideDown':'slideUp')]()
jQuery functions are still just JavaScript functions, so the same rules apply to them as any other JS functions.
You can call methods of an object objectVar as follows:
objVar.method();
objVar["method"]();
var methodName = "method";
objVar[methodName]();
Your question mentioned using window[]() - that applies to global functions, since they are essentially properties of window (if running JS in the browser, of course).
In the case of jQuery, you can therefore do this:
var methodName = "hide";
$(someSelector)[methodName]();
$(someSelector)[anyJSExpressionThatReturnsAStringThatIsAjQueryMethod]();
EDIT: I just saw the new version of the question. The line of code shown with the ?: operator selecting the method name should give the same effect as the if/else. I've used similar code myself with no problems, and it works fine in the fiddle that Jason P provided. Note that since your motivation here seems to be about making the code shorter you can omit all of the parentheses from the expression in the [] and just do this:
$("#gridViewContainer")[msg.length > 0?'slideDown':'slideUp']();
...or even omit the > 0 part since msg.length will be truthy when non-zero:
$("#gridViewContainer")[msg.length ?'slideDown':'slideUp']();