zhu-ting / JavaScript_Ninja

take you from an apprentice to a ninja
1 stars 0 forks source link

Chapter03 First-class functions for the novice: definitions and arguments #3

Open zhu-ting opened 6 years ago

zhu-ting commented 6 years ago

When it comes down to brass tacks【实质问题】, the main difference between writing JavaScript code like the average and writing it like a JavaScript ninja is understanding JavaScript as a functional language. The level of sophistication of all the code you’ll ever write in JavaScript hinges on this realization.

zhu-ting commented 6 years ago

Significant chunks explain just how the nature of functions as first-class objects can be exploited to our great benefit. But first, let’s take a look at some of the actions we can take with objects. In JavaScript, objects enjoy certain capabilities:

zhu-ting commented 6 years ago

Functions as first-class objects

Functions in JavaScript possess all the capabilities of objects and are thus treated like any other object in the language. We say that functions are first-class objects, which can also be:

zhu-ting commented 6 years ago

Callback functions

Whenever we set up a function to be called at a later time, whether by the browser in the event-handling phase or by other code, we’re setting up a callback. The term stems from the fact that we’re establishing a function that other code will later “call back” at an appropriate point of execution.

var text = "Domo arigato!";
console.log("Before defining functions");
function useless(ninjaCallback) {
  console.log("In useless function");
  return ninjaCallback();
}
function getText() {
  console.log("In getText function");
  return text;
}
console.log("Before making all the calls");
alert(useless(getText) === text,
       "The useless function works! " + text);
console.log("After the calls have been made");
zhu-ting commented 6 years ago

Before defining functions Before making all the calls In useless function In getText function

Alert('true') After the calls have been made

zhu-ting commented 6 years ago
var text = 'Domo arigato!';
function useless(ninjaCallback) {
  return ninjaCallback();
}
console.log(useless(function () { return text;}) === text, "The useless function works! " + text);

VM544:5 true "The useless function works! Domo arigato!"

zhu-ting commented 6 years ago

2018-08-30 3 19 57

zhu-ting commented 6 years ago

Now let’s consider a use of callbacks that will greatly simplify how we sort collections.

SORTING WITH A COMPARATOR

All JavaScript arrays have access to the sort method that requires us only to define a comparison algorithm that tells the sort algorithm how the values should be ordered. This is where callbacks jump in! Instead of letting the sort algorithm decide what values go before other values, we’ll provide a function that performs the comparison. We’ll give the sort algorithm access to this function as a callback, and the algorithm will call the callback whenever it needs to make a comparison. The callback is expected to return a positive number if the order of the passed values should be reversed, a negative number if not, and zero if the values are equal; subtracting the compared values produces the desired return value to sort the array:

var values = [0, 3, 2, 5, 7, 4, 8, 1];
    values.sort(function(value1, value2){ 
        return value1 - value2;
});

The functional approach allows us to create a function as a standalone entity, just as we can any other object type, and to pass it as an argument to a method, just like any other object type, which can accept it as a parameter, just like any other object type. It’s that first-class status coming into play.

zhu-ting commented 6 years ago

Fun with functions as objects

In this section, we’ll examine ways to exploit the similarities that functions share with other object types. One capability that might be surprising is that there’s nothing stopping us from attaching properties to functions:

// Creates an object and assigns a new property to it
var ninja = {};
ninja.name = "hitsuke";
// Creates a function and assigns a new property to it
var wieldSword = function(){};
wieldSword.swordType = "katana";

Let’s look at a couple of the more interesting things that can be done with this capability:

zhu-ting commented 6 years ago

Storing functions

var store = {
  nextId: 1,
  cache: {},
  add: function(fn) {
    if (!fn.id) {
      fn.id = this.nextId++;
      this.cache[fn.id] = fn;
      return true;
} }
};
function ninja(){}
assert(store.add(ninja),
       "Function was safely added.");
assert(!store.add(ninja),
       "But it was only added once.");
zhu-ting commented 6 years ago

Self-memoizing functions

zhu-ting commented 6 years ago

3.3 Defining functions

JavaScript provides a couple of ways to define functions, which can be divided into four groups:

zhu-ting commented 6 years ago
screen shot 2018-08-31 at 00 01 59

Besides the position in code where they’re placed, there’s one more difference between function declarations and function expressions: For function declarations, the function name is mandatory, whereas for function expressions it’s completely optional.

zhu-ting commented 6 years ago

Parentheses around function expressions One more thing might be nagging you about the way we’ve immediately called our func- tion expression: the parentheses around the function expression itself. Why do we even need those? The reason is purely syntactical. The JavaScript parser has to be able to easily differentiate between function declarations and function expressions. If we leave out the parentheses around the function expression, and put our immediate call as a separate statement function(){}(3), the JavaScript parser will start pro- cessing it, and will conclude, because it’s a separate statement starting with the key- word function, that it’s dealing with a function declaration. Because every function declaration has to have a name (and here we didn’t specify one), an error will be thrown. To avoid this, we place the function expression within parentheses, signaling to the JavaScript parser that it’s dealing with an expression, and not a statement.

Immediate function is an important concept in JavaScript development because it allows us to mimic modules in JavaScript. We’ll focus on this application of IIFEs in chapter 11.

+function(){}();
-function(){}();
!function(){}();
~function(){}();
zhu-ting commented 6 years ago

3.4 Arguments and function parameters实参和形参