Working of javascript inline functions - javascript

I am not able to grasp how function(match, p1, p2) is working.
What is use of match parameter? The code breaks if I don't write match parameter.
function incrementString(input) {
if (isNaN(parseInt(input[input.length - 1]))) return input + '1';
return input.replace(/(0*)([0-9]+$)/, function(match, p1, p2) {
var up = parseInt(p2) + 1;
return up.toString().length > p2.length ? p1.slice(0, -1) + up : p1 + up;
});
}
P.S: I am new entirely using Js for development. However, I have been working on JSF and Java since past few years.

From MDN:
str.replace(regexp|substr, newSubStr|function[, flags])
In that case, we can see that two arguments are passed to replace, a regular expression literal and a function expression. So that's:
str.replace(regexp, function)
and MDN tells us what they are:
function (replacement)A function to be invoked to create the new
substring (to put in place of the substring received from parameter
1). The arguments supplied to this function are described in the "Specifying a function as a parameter" section below.
and
The arguments to the function are as follows:
etc. etc. I won't quote the entire table.
If you leave the match argument out of the parameter list, then the values assigned to p1 and p2 will be the first and second argument instead of the second and third. Those won't be the values you need.
It would be like taking this code:
function call_with_one_two_three(f) {
f(1,2,3);
}
call_with_one_two_three(function (one, two, three) {
alert(two + three);
});
And deciding that since you weren't using one you didn't need it:
function call_with_one_two_three(f) {
f(1,2,3);
}
call_with_one_two_three(function (two, three) {
alert(two + three);
});
That giving you two + three as 3.
In short: The position of arguments matters (and the name doesn't).

Related

Confused on how to approach this (writing a function, returning a string)

So I have to write a function plusLettuce that accepts one parameter as an argument and the function has to return a string that has my argument and the phrase "plus lettuce". So I'm guessing if I type in plusLettuce("Onions"); into my console I should get "Onions plus lettuce" as my output.
This is what I have so far .. so I wrote my function with a parameter and I'm confused what to do next. (I'm a total noon sorry) Do I make a variable word? I'm just stuck on what my next step has to be. Please help.
var plusLettuce = function(word) {
var word =
}
You can use the addition operator + to concatenate strings, and the return statement to return the result of the function call:
var plusLettuce = function(word) {
return word + " plus lettuce";
};
plusLettuce("Onions"); // "Onions plus lettuce"
JS uses + for string concatenation.
You're also overwriting your word (which is already there, in your function), when you declare a new var word.
So
function plusLettuce (phrase) {
// I don't say `var phrase`, because it already exists
var phrasePlusLettuce = phrase + " plus lettuce"; // note the space at the start
return phrasePlusLettuce;
}
When you give a function a parameter, it automatically becomes a local variable for that function. Meaning that you can immediately use it as a variable too.
var plusLettuce = function(word) { // I take the var word from here...
return word + ' plus lettuce'; // ...and then use it here.
};
console.log(plusLettuce('Onions')); // This is where I assign the var word.
So what's happening here is that I'm telling the plusLettuce function to return whatever the user gave as a parameter plus ' plus lettuce'. Then call it in the console.log();
In programming this is called string concatenation, what your been asked to do is make a static string concatenate with a dynamic one.
function plusLettuce (phrase){
var staticWord = ' plus lettuce';
return phrase + staticWord
}
console.log(plusLettuce('Onions'))
Remember that a parameter/argument is a variable accessible by the function only, the static part meaning it will always be the same can be a assign to a variable to keep the code clean. and the dynamic part which is the parameter will be different every time according to what is passed on to the function each time is called.

Javascript Variable Reference

Something I don't understand, which I'm sure someone with any simple knowledge of Javascript will get;
How does the 'm' variable referenced in this replace function actually refer to the input from the str - I don't understand how it takes the str as m?
str = str.replace("whatevers",function(m){ return m.toUpperCase(); })
Many thanks in advance. Tyler.
Each function defines how any functions passed in are used. The documentation for String.prototype.replace() explains how it's used in the section on specifying a function as a parameter.
Somewhere in the implementation of replace, that function you're passing in is called with several arguments. The full example is:
function replacer(match, p1, p2, p3, offset, string) {
return "replacement_text";
}
In the context of string replacing, if you pass in a function as the second parameter like the way you're doing, the first argument of that function that you pass in (in your case 'm') will be anything that matches your initial first argument (in this case "whatevers"). Once it finds a match, that gets assigns to 'm', and then it will perform the toUpperCase function on that variable 'm'.

TypeError: Cannot read property 'slice' of undefined

I use this script for page pagination like in this tutorial http://fdietz.github.io/recipes-with-angular-js/common-user-interface-patterns/paginating-through-client-side-data.html
app.filter('offset', function() {
return function(input, start) {
start = parseInt(start, 10);
return input.slice(start);
};
});
Everything went fine, except that I got an error
TypeError: Cannot read property 'slice' of undefined
at k.<anonymous> (http://www.foo.com/43267ztX/default/:18:17)
at e (http://www.foo.com/43267ztX/default/js/angular.min.js:171:180)
at db.| (http://www.foo.com/43267ztX/default/js/angular.min.js:160:65)
at F.constant (http://www.foo.com/43267ztX/default/js/angular.min.js:170:82)
at db.| (http://www.foo.com/43267ztX/default/js/angular.min.js:160:70)
at F.constant (http://www.foo.com/43267ztX/default/js/angular.min.js:170:82)
at Object.$watch.p (http://www.foo.com/43267ztX/default/js/angular.min.js:107:159)
at k.$digest (http://www.foo.com/43267ztX/default/js/angular.min.js:109:78)
at k.$apply (http://www.foo.com/43267ztX/default/js/angular.min.js:112:173)
at h (http://www.foo.com/43267ztX/default/js/angular.min.js:72:300) </pre>
Try:
app.filter('offset', function(start) {
return function(input) {
start = parseInt(start, 10);
return input.slice(start);
};
});
What does this mean?
Each filter must take an input and return an output.
Each filter must be built from criteria. This means, in the example: given a certain start, give me a function which takes an input and produces an output slicing (start, 10).
It's much like the decorator pattern.
Don't believe me? Read the official doc to see how filters are high-order functions (functions that return functions - this functions become criteria factories, and the resulting function is used only on the purpose of the defined function).
What were your errors?
In the wrapper function (let's say), you must only give parameters which will have use on defining the function which will be the actual filter. You will use this filter as{{ myArray|offset:3 }}, and only receive ONE parameter: (start) which will, in this case, 3.
The wrapped function will take exactly one parameter (the name does not matter).
To illustrate this even more: (editing...)
Let's make a new filter, one with more caps than yours for one parameter:
app.filter('limit', function(start, count) {
start = parseInt(start);
count = parseInt(count);
return function(input) {
return input.slice(start, start + count);
}
});
Each filter is kind of a factory (actually: it is a factory). This one takes two parameters and yields the actual filter. The actual filter is a function that takes a parameter and returns a filtered value. The inner criteria is defined by the parameters I passed to the wrapper function.
So when you use it like this:
{{ myArray | limit:5:5 }}
You say something like:
Take the arguments (5, 5).
Create a function which takes an input and slices it on (5, 10), and return it.
Apply that returned function to myArray.

How can a parameter exist when no argument is passed?

I'm new to Javascript, although I have a .net background. Typically in .NET (as well as many other languages), if a method requires a parameter to be passed, you have to pass it (or else compiler error due to incorrect signature). This also appears to be the case in JavaScript, but not all cases it would appear.
This doesn't appear to be the case in Javascript.
As a working example, please refer to line 61
http://www.humblesoftware.com/flotr2/#!basic-axis
Line 61 is tickFormatter: ticksFn,
I understand that tickFormatter is calling a function called ticksFn but line 29 shows
function ticksFn(n) {
return '(' + n + ')';
}
'ticksFn' requires a value (n) to be passed, yet, we never pass it.
Despite that, javascript still gets it right and I can't find out how, nor can I work/understand what to search for to do more research
You never call it at all. You pass the function itself as an argument (or rather as the value of a property of an object that is an argument).
graph = Flotr.draw(container, [ /* ... */], {
xaxis : {
noTicks : 7, // Display 7 ticks.
tickFormatter : ticksFn, // Displays tick values between brackets.
// …
Your third party library code is responsible for actually calling that function, and it does so with an argument.
In javascript it is not required to pass the parameters for a function as a value of undefined is passed if you don't.
So a function:
function ticksFn(n) {
return '(' + n + ')';
}
Can be invoked:
ticksFn();
Without any problem and the value of the n will be undefined..
Alternatively a function defined with no arguments:
function ticksFn() {
return '(' + arguments[0] + ')';
}
And calling:
ticksFn(10);
arguments[0] will be 10. and accordingly you can read any number of arguments.
That was a quick tutorial about javascript functions.. now about your code.. javascript is a function oriented language and so writing the function name without parentheses actually hands reference on the function rather than calling the function itself..

Crockford's deentityify method - p.41 of The Good Parts

In a fit of self-improvement, I'm reading (and rereading) TGP by Señor Crockford. I cannot, however, understand the middlemost part of his deentityify method.
...
return this.replace(...,
function (a, b) {
var r = ...
}
);
I think I understand that:
this.replace is passed two arguments, the regex as the search value and the function to generate the replacement value;
the b is used to access the properties in the entity object;
the return ? r : a; bit determines whether to return the text as is or the value of the appropriate property in entity.
What I don't get at all is how the a & b are provided as arguments into function (a, b). What is calling this function? (I know the whole thing is self-executing, but that doesn't really clear it up for me. I guess I'm asking how is this function being called?)
If someone was interested in giving a blow by blow analysis akin to this, I'd really appreciate it, and I suspect others might too.
Here's the code for convenience:
String.method('deentityify', function ( ) {
var entity = {
quot: '"',
lt: '<',
gt: '>'
};
return function () {
return this.replace(
/&([^&;]+);/g,
function (a, b) {
var r = entity[b];
return typeof r === 'string' ? r : a;
}
);
};
}());
a isn't the numerical offset, it's the matched substring.
b (in this case) is the first grouping, i.e., the match minus the surrounding & and ;.
The method checks to make sure the entity exists, and that it's a string. If it is, that's the replacement value, otherwise it's replaced by the original value, minus the & and ;
The replace function can take a function as the second parameter.
This function is then called for every match, with a signature that depends on the number of groups in the regular expression being searched for. If the regexp does not contain any capturing groups, a will be the matched substring, b the numerical offset in the whole string. For more details, refer to the MDN documentation.

Categories