- 3.1 Declaring Functions
- 3.2 Higher-Order Functions
- 3.3 Function Literals
- 3.4 Arrow Functions
- 3.5 Functional Array Processing
- 3.6 Closures
- 3.7 Hard Objects
- 3.8 Strict Mode
- 3.9 Testing Argument Types
- 3.10 Supplying More or Fewer Arguments
- 3.11 Default Arguments
- 3.12 Rest Parameters and the Spread Operator
- 3.13 Simulating Named Arguments with Destructuring
- 3.14 Hoisting
- 3.15 Throwing Exceptions
- 3.16 Catching Exceptions
- 3.17 The finally Clause
- Exercises
Exercises
What does theindexOffunction of Section 3.1, “Declaring Functions” (page 51), do when an object is passed instead of an array?
Rewrite theindexOffunction of Section 3.1, “Declaring Functions” (page 51), so that it has a single return at the end.
Write a functionvalues(f, low, high)that yields an array of function values[f(low), f(low + 1), . . ., f(high)].
Thesortmethod for arrays can take an argument that is a comparison function with two parameters—say,xandy. The function returns a negative integer ifxshould come beforey, zero ifxandyare indistinguishable, and a positive integer ifxshould come aftery. Write calls, using arrow functions, that sort:
An array of positive integers by decreasing order
An array of people by increasing age
An array of strings by increasing length
Using the “hard objects” technique of Section 3.7, “Hard Objects” (page 59), implement aconstructCountermethod that produces counter objects whosecountmethod increments a counter and yields the new value. The initial value and an optional increment are passed as parameters. (The default increment is 1.)
const myFirstCounter = constructCounter(0, 2) console.log(myFirstCounter.count()) // 0 console.log(myFirstCounter.count()) // 2
A programmer thinks that “named parameters are almost implemented in JavaScript, but order still has precedence,” offering the following “evidence” in the browser console:
function f(a=1, b=2){ console.log(`a=${a}, b=${b}`) } f() // a=1, b=2 f(a=5) // a=5, b=2 f(a=7, b=10) // a=7, b=10 f(b=10, a=7) // Order is required: a=10, b=7
What is actually going on? (Hint: It has nothing to do with named parameters. Try it in strict mode.)
Write a functionaveragethat computes the average of an arbitrary sequence of numbers, using a rest parameter.
What happens when you pass a string argument to a rest parameter...str? Come up with a useful example to take advantage of your observation.
Complete themkStringfunction of Section 3.13, “Simulating Named Arguments with Destructuring” (page 66).
The archaicvarkeyword interacts poorly with closures. Consider this example:
for (var i = 0; i < 10; i++) { setTimeout(() => console.log(i), 1000 * i) }
What does this code snippet print? Why? (Hint: What is the scope of the variablei?) What simple change can you make to the code to print the numbers 0, 1, 2, . . . , 9 instead?
Consider this declaration of the factorial function:
const fac = n => n > 1 ? n * fac(n - 1) : 1
Explain why this only works because of variable hoisting.
在草率(非严格)模式下,可以decl功能ared inside a nested block, and they are hoisted to the enclosing function or script. Try out the following example a few times:
if (Math.random() < 0.5) { say('Hello') function say(greeting) { console.log(`${greeting}!`) } } say('Goodbye')
Depending on the result ofMath.random, what is the outcome? What is the scope ofsay? When is it initialized? What happens when you activate strict mode?
Implement anaveragefunction that throws an exception if any of its arguments is not a number.
Some programmers are confused by statements that contain all three oftry/catch/finallybecause there are so many possible pathways of control. Show how you can always rewrite such a statement using atry/catchstatement and atry/finallystatement.