Danh mục

Test Driven JavaScript Development- P7

Số trang: 20      Loại file: pdf      Dung lượng: 202.07 KB      Lượt xem: 13      Lượt tải: 0    
10.10.2023

Xem trước 2 trang đầu tiên của tài liệu này:

Thông tin tài liệu:

Test Driven JavaScript Development- P7:This book is about programming JavaScript for the real world, using the techniquesand workflow suggested by Test-Driven Development. It is about gaining confidencein your code through test coverage, and gaining the ability to fearlessly refactor andorganically evolve your code base. It is about writing modular and testable code. Itis about writing JavaScript that works in a wide variety of environments and thatdoesn’t get in your user’s way.
Nội dung trích xuất từ tài liệu:
Test Driven JavaScript Development- P7 6.4 Memoization 113 Listing 6.26 Memoizing the Fibonacci sequence in a closure var fibonacci = (function () { var cache = {}; function fibonacci(x) { if (x < 2) { return 1; } if (!cache[x]) { cache[x] = fibonacci(x - 1) + fibonacci(x - 2); } return cache[x]; } return fibonacci; }()); This alternative version of fibonacci runs many orders of magnitude faster than the original one, and by extension is capable of calculating more numbers in the sequence. However, mixing computation with caching logic is a bit ugly. Again, we will add a function to Function.prototype to help separate concerns. The memoize method in Listing 6.27 is capable of wrapping a method, adding memoization without cluttering the calculation logic. Listing 6.27 A general purpose memoize method if (!Function.prototype.memoize) { Function.prototype.memoize = function () { var cache = {}; var func = this; return function (x) { if (!(x in cache)) { cache[x] = func.call(this, x); } return cache[x]; }; }; }Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. From the Library of WoweBook.Com 114 Applied Functions and Closures This method offers a clean way to memoize functions, as seen in Listing 6.28. Listing 6.28 Memoizing the fibonacci function TestCase(FibonacciTest, { test calculate high fib value with memoization: function () { var fibonacciFast = fibonacci.memoize(); assertEquals(1346269, fibonacciFast(30)); } }); The memoize method offers a clean solution but unfortunately only deals with functions that take a single argument. Limiting its use further is the fact that it blindly coerces all arguments to strings, by nature of property assignment, which will be discussed in detail in Chapter 7, Objects and Prototypal Inheritance. To improve the memoizer, we would need to serialize all arguments to use as keys. One way to do this, which is only slightly more complex than what we already have, is to simply join the arguments, as Listing 6.29 does. Listing 6.29 A slightly better memoize method if (!Function.prototype.memoize) { Function.prototype.memoize = function () { var cache = {}; var func = this; var join = Array.prototype.join; return function () { var key = join.call(arguments); if (!(key in cache)) { cache[key] = func.apply(this, arguments); } return cache[key]; }; }; } This version will not perform as well as the previous incarnation because it both calls join and uses apply rather than call, because we no longer can assume the number of arguments. Also, this version will coerce all arguments to strings as before, meaning it cannot differentiate between, e.g., 12 and 12 passed asPlease purchase PDF Split-Merge on www.verypdf.com to remove this watermark. From the Library of WoweBook.Com 6.5 Summary 115 arguments. Finally, because the cache key is generated by joining the parameters with a comma, string arguments that contain commas can cause the wrong value to be loaded, i.e., (1, b) would generate the same cache key as (1,b). It is possible to implement a proper serializer that can embed type information about arguments, and possibly use tddjs.uid to serialize object and function arguments, but doing so would impact the performance of memoize in a noticeable way such that it would only help out in cases that could presumably be better optimized in other ways. Besides, serializing object arguments using tddjs.uid, although simple and fast, would cause the method to possibly assign new properties to arguments. That would be unexpected in most cases and should at the very least be properly documented. 6.5 Summary In this chapter we have worked through a handful of practical function examples with a special focus on closures. With an understanding of the scope chain from Chapter 5, Functions, we have seen how inner functions can keep private state in free variables. Through examples we have seen how to make use of the scope and state offered by closures to solve a range of problems in an elegant way. Some of the functions developed in this chapter will make appearances in upcoming chapters as we build on top of them and add more useful interfaces to the tddjs object. Throughout the book we will also meet plenty more examples of using clos ...

Tài liệu được xem nhiều: