Home Web Front-end JS Tutorial Lazy function definition mode usage_javascript tips

Lazy function definition mode usage_javascript tips

May 16, 2016 pm 07:08 PM
Instructions

This article explains a functional-programming design pattern, which I call Lazy Function Definition. I've found this pattern useful in JavaScript more than once, especially when writing cross-browser, efficient libraries.

Warm-up questions

Write a function foo, which returns a Date object. This object saves the time when foo is first called.

Method 1: Technology from ancient times

This simplest solution uses the global variable t to save the Date object. The first time foo is called, the time will be saved in t. Subsequent calls to foo will only return the value stored in t.

var t;  
function foo() {  
    if (t) {  
        return t;  
    }  
    t = new Date();  
    return t;  
}
Copy after login

But there are two problems with this code. First, the variable t is a redundant global variable and may be changed between calls to foo. Second, the code is not optimized for efficiency at call time because the condition must be evaluated every time foo is called. Although evaluating the condition does not appear to be inefficient in this example, real-world practical examples often have extremely expensive condition evaluation, such as in if-else-else-... structures.

Method 2: Module Pattern

We can make up for the shortcomings of the first method through the module pattern that is attributed to Cornford and Crockford. Use a closure to hide the global variable t so that only code within foo can access it.

var foo = (function() {  
    var t;  
    return function() {  
        if (t) {  
            return t;  
        }  
        t = new Date();  
        return t;  
    }  
})();
Copy after login

But this still does not optimize the efficiency of the call, because each call to foo still requires an evaluation condition.
Although the module pattern is a powerful tool, I firmly believe that it is used in the wrong place in this situation.
Method 3: Functions as objects
Since JavaScript functions are also objects, they can have attributes. Based on this, we can implement a solution that is similar in quality to the module pattern.

function foo() {  
    if (foo.t) {  
        return foo.t;  
    }  
    foo.t = new Date();  
    return foo.t;  
}
Copy after login

In some cases, function objects with properties can produce cleaner solutions. I think this approach is conceptually simpler than the pattern module approach.
This solution avoids the global variable t in the first method, but it still cannot solve the conditional evaluation caused by each call to foo.
Method 4: Lazy function definition
Now, this is the reason why you are reading this article:

var foo = function() {  
    var t = new Date();  
    foo = function() {  
        return t;  
    };  
    return foo();  
};
Copy after login

当foo首次调用,我们实例化一个新的Date对象并重置 foo到一个新的函数上,它在其闭包内包含Date对象。在首次调用结束之前,foo的新函数值也已调用并提供返回值。

接下来的foo调用都只会简单地返回t保留在其闭包内的值。这是非常快的查找,尤其是,如果之前那些例子的条件非常多和复杂的话,就会显得很高效。

弄清这种模式的另一种途径是,外围(outer)函数对foo的首次调用是一个保证(promise)。它保证了首次调用会重定义foo为一个非常有用的函数。笼统地说,术语“保证” 来自于Scheme的惰性求值机制(lazy evaluation mechanism)。每一位JavaScript程序员真的都应该 学习Scheme ,因为它有很多函数式编程相关的东西,而这些东西会出现在JavaScript中。

确定页面滚动距离

编写跨浏览器的JavaScript, 经常会把不同的浏览器特定的算法包裹在一个独立的JavaScript函数中。这就可以通过隐藏浏览器差异来标准化浏览器API,并让构建和维护复杂的页面特性的JavaScript更容易。当包裹函数被调用,就会执行恰当的浏览器特定的算法。

在拖放库中,经常需要使用由鼠标事件提供的光标位置信息。鼠标事件给予的光标坐标相对于浏览器窗口而不是页面。加上页面滚动距离鼠标的窗口坐标的距离即可得到鼠标相对于页面的坐标。所以我们需要一个反馈页面滚动的函数。演示起见,这个例子定义了一个函数getScrollY。因为拖放库在拖拽期间会持续运行,我们的getScrollY必须尽可能高效。

不过却有四种不同的浏览器特定的页面滚动反馈算法。Richard Cornford在他的feature detection article 文章中提到这些算法。最大的陷阱在于这四种页面滚动反馈算法其中之一使用了 document.body. JavaScript库通常会在HTML文档的加载,与此同时docment.body并不存在。所以在库载入的时候,我们并不能使用特性检查(feature detection)来确定使用哪种算法。

考虑到这些问题,大部分JavaScript库会选择以下两种方法中的一种。第一个选择是使用浏览器嗅探navigator.userAgent,为该浏览器创建高效、简洁的getScrollY. 第二个更好些的选择是getScrollY在每一次调用时都使用特性检查来决定合适的算法。但是第二个选择并不高效。

好消息是拖放库中的getScrollY只会在用户与页面的元素交互时才会用到。如果元素业已出现在页面中,那么document.body也会同时存在。getScrollY的首次调用,我们可以使用惰性函数定义模式结合特性检查来创建高效的getScrollY.

var getScrollY = function() {  
    if (typeof window.pageYOffset == 'number') {  
        getScrollY = function() {  
            return window.pageYOffset;  
        };  
    } else if ((typeof document.compatMode == 'string') &&  
               (document.compatMode.indexOf('CSS') >= 0) &&  
               (document.documentElement) &&  
               (typeof document.documentElement.scrollTop == 'number')) {  
        getScrollY = function() {  
            return document.documentElement.scrollTop;  
        };  
    } else if ((document.body) &&  
               (typeof document.body.scrollTop == 'number')) {  
      getScrollY = function() {  
          return document.body.scrollTop;  
      }  
    } else {  
      getScrollY = function() {  
          return NaN;  
      };  
    }  
    return getScrollY();  
}
Copy after login

总结
惰性函数定义模式让我可以编写一些紧凑、健壮、高效的代码。用到这个模式的每一次,我都会抽空赞叹JavaScript的函数式编程能力。

JavaScript同时支持函数式和面向对象便程。市面上有很多重点着墨于面向对象设计模式的书都可以应用到JavaScript编程中。不过却没有多少书涉及函数式设计模式的例子。对于JavaScript社区来说,还需要很长时间来积累良好的函数式模式。
更新:
这个模式虽然有趣,但由于大量使用闭包,可能会由于内存管理的不善而导致性能问题。来自 FCKeditor 的FredCK改进了getScrollY,既使用了这种模式,也避免了闭包:

var getScrollY = function() {  
    if (typeof window.pageYOffset == 'number')  
        return (getScrollY = getScrollY.case1)();  
    var compatMode = document.compatMode;  
    var documentElement = document.documentElement;  
    if ((typeof compatMode == 'string') &&  
               (compatMode.indexOf('CSS') >= 0) &&  
               (documentElement) &&  
               (typeof documentElement.scrollTop == 'number'))  
        return (getScrollY = getScrollY.case2)();  
    var body = document.body ;  
    if ((body) &&  
               (typeof body.scrollTop == 'number'))  
        return (getScrollY = getScrollY.case3)();  
    return (getScrollY = getScrollY.case4)();  
};  
getScrollY.case1 = function() {  
    return window.pageYOffset;  
};  
getScrollY.case2 = function() {  
    return documentElement.scrollTop;  
};  
getScrollY.case3 = function() {  
    return body.scrollTop;  
};  
getScrollY.case4 = function() {  
        return NaN;  
};
Copy after login
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to use DirectX repair tool? Detailed usage of DirectX repair tool How to use DirectX repair tool? Detailed usage of DirectX repair tool Mar 15, 2024 am 08:31 AM

The DirectX repair tool is a professional system tool. Its main function is to detect the DirectX status of the current system. If an abnormality is found, it can be repaired directly. There may be many users who don’t know how to use the DirectX repair tool. Let’s take a look at the detailed tutorial below. 1. Use repair tool software to perform repair detection. 2. If it prompts that there is an abnormal problem in the C++ component after the repair is completed, please click the Cancel button, and then click the Tools menu bar. 3. Click the Options button, select the extension, and click the Start Extension button. 4. After the expansion is completed, re-detect and repair it. 5. If the problem is still not solved after the repair tool operation is completed, you can try to uninstall and reinstall the program that reported the error.

Introduction to HTTP 525 status code: explore its definition and application Introduction to HTTP 525 status code: explore its definition and application Feb 18, 2024 pm 10:12 PM

Introduction to HTTP 525 status code: Understand its definition and usage HTTP (HypertextTransferProtocol) 525 status code means that an error occurred on the server during the SSL handshake, resulting in the inability to establish a secure connection. The server returns this status code when an error occurs during the Transport Layer Security (TLS) handshake. This status code falls into the server error category and usually indicates a server configuration or setup problem. When the client tries to connect to the server via HTTPS, the server has no

How to use Baidu Netdisk-How to use Baidu Netdisk How to use Baidu Netdisk-How to use Baidu Netdisk Mar 04, 2024 pm 09:28 PM

Many friends still don’t know how to use Baidu Netdisk, so the editor will explain how to use Baidu Netdisk below. If you are in need, hurry up and take a look. I believe it will be helpful to everyone. Step 1: Log in directly after installing Baidu Netdisk (as shown in the picture); Step 2: Then select "My Sharing" and "Transfer List" according to the page prompts (as shown in the picture); Step 3: In "Friend Sharing", you can share pictures and files directly with friends (as shown in the picture); Step 4: Then select "Share" and then select computer files or network disk files (as shown in the picture); Fifth Step 1: Then you can find friends (as shown in the picture); Step 6: You can also find the functions you need in the "Function Treasure Box" (as shown in the picture). The above is the editor’s opinion

Learn to copy and paste quickly Learn to copy and paste quickly Feb 18, 2024 pm 03:25 PM

How to use the copy-paste shortcut keys Copy-paste is an operation we often encounter when using computers every day. In order to improve work efficiency, it is very important to master the copy and paste shortcut keys. This article will introduce some commonly used copy and paste shortcut keys to help readers perform copy and paste operations more conveniently. Copy shortcut key: Ctrl+CCtrl+C is the shortcut key for copying. By holding down the Ctrl key and then pressing the C key, you can copy the selected text, files, pictures, etc. to the clipboard. To use this shortcut key,

How to correctly use the win10 command prompt for automatic repair operations How to correctly use the win10 command prompt for automatic repair operations Dec 30, 2023 pm 03:17 PM

The longer the computer is used, the more likely it is to malfunction. At this time, friends need to use their own methods to repair it. So what is the easiest way to do it? Today I will bring you a tutorial on how to repair using the command prompt. How to use win10 automatic repair command prompt: 1. Press "Win+R" and enter cmd to open the "command prompt" 2. Enter chkdsk to view the repair command 3. If you need to view other places, you can also add other partitions such as "d" 4. Enter the execution command chkdskd:/F. 5. If it is occupied during the modification process, you can enter Y to continue.

What is the KMS activation tool? How to use the KMS activation tool? How to use KMS activation tool? What is the KMS activation tool? How to use the KMS activation tool? How to use KMS activation tool? Mar 18, 2024 am 11:07 AM

The KMS Activation Tool is a software tool used to activate Microsoft Windows and Office products. KMS is the abbreviation of KeyManagementService, which is key management service. The KMS activation tool simulates the functions of the KMS server so that the computer can connect to the virtual KMS server to activate Windows and Office products. The KMS activation tool is small in size and powerful in function. It can be permanently activated with one click. It can activate any version of the window system and any version of Office software without being connected to the Internet. It is currently the most successful and frequently updated Windows activation tool. Today I will introduce it Let me introduce to you the kms activation work

How to merge cells using shortcut keys How to merge cells using shortcut keys Feb 26, 2024 am 10:27 AM

How to use the shortcut keys for merging cells In daily work, we often need to edit and format tables. Merging cells is a common operation that can merge multiple adjacent cells into one cell to improve the beauty of the table and the information display effect. In mainstream spreadsheet software such as Microsoft Excel and Google Sheets, the operation of merging cells is very simple and can be achieved through shortcut keys. The following will introduce the shortcut key usage for merging cells in these two software. exist

How to use potplayer-How to use potplayer How to use potplayer-How to use potplayer Mar 04, 2024 pm 06:10 PM

Potplayer is a very powerful media player, but many friends still don’t know how to use potplayer. Today I will introduce how to use potplayer in detail, hoping to help everyone. 1. PotPlayer shortcut keys. The default common shortcut keys for PotPlayer player are as follows: (1) Play/pause: space (2) Volume: mouse wheel, up and down arrow keys (3) forward/backward: left and right arrow keys (4) bookmark: P- Add bookmarks, H-view bookmarks (5) full screen/restore: Enter (6) multiple speeds: C-accelerate, 7) Previous/next frame: D/

See all articles