什么是"x = x ||"{}";JavaScript中的技巧-以及如何影响此IIFE? [英] What is the "x = x || {}" technique in JavaScript - and how does it affect this IIFE?

查看:56
本文介绍了什么是"x = x ||"{}";JavaScript中的技巧-以及如何影响此IIFE?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,是一个伪代码示例:

First, a pseudo code example:

;(function(foo){

    foo.init = function(baz) { ... }

    foo.other = function() { ... }

    return foo;

}(window.FOO = window.FOO || {}));

这样称呼:

FOO.init();

我的问题:

  • window.FOO = window.FOO ||的技术名称/描述是什么?{} ?
  • 我了解代码的作用...出于我的询问原因,请参见下文.

    I understand what the code does... See below for my reason(s) for asking.

    我这样称呼传入的全局对象:

    I'm calling the passed in global like so:

    ;(function(foo){
        ... foo vs. FOO, anyone else potentially confused? ...
    }(window.FOO = window.FOO || {}));
    

    ...但是我只是不喜欢称呼小写的" foo ",考虑到全局被称为大写的 FOO ...这似乎令人困惑.

    ... but I just don't like calling that lowercase "foo", considering that the global is called capitalized FOO... It just seems confusing.

    如果我知道这项技术的技术名称,我可以说:

    If I knew the technical name of this technique, I could say:

    ;(function(technicalname){
        ... do something with technicalname, not to be confused with FOO ...
    }(window.FOO = window.FOO || {}));
    

    我看到了一个最近的(很棒的)例子,他们称其为" exports ":

    I've seen a recent (awesome) example where they called it "exports":

    ;(function(exports){
        ...
    }(window.Lib = window.Lib || {}));
    

    我想我只是想标准化我的编码约定...我想学习专业人员的做法以及他们的想法(这就是为什么我在这里问这个问题!)!

    I guess I'm just trying to standardize my coding conventions... I'd like to learn what the pros do and how they think (that's why I'm asking here)!

    推荐答案

    模式

    (function (foo) {
        ...code...
        foo.bar = baz;
        ...more code...
    }(window.FOO = window.FOO || {});
    

    您描述的模式没有正式名称,因为它是三个单独的模式组合而成.每个模式都有多个名称,但是在这篇文章中,我将使用以下术语:

    There is no formal name for the pattern you describe, because it's three separate patterns combined. Each pattern goes by multiple names, but for this post I will use the following terminology:

    • 关闭
    • 别名
    • 命名空间扩展名

    整个模式的基础是 closure .它只是一个用于定义变量和函数范围的函数,这样它们就不会污染全局名称空间:

    The base of the entire pattern is the closure. It is simply a function that is used to scope variables and functions such that they don't pollute the global namespace:

    //these declare window.foo and window.bar respectively
    //as such, they pollute the global namespace
    var foo;
    function bar() {}
    

    在这种情况下,请关闭立即调用的功能表达式(IIFE)

    (function () {
        //these declare foo and bar within the function
        //but they are not accessible outside the function
        var foo;
        function bar() {}
    }());
    

    将变量保留在闭包中的优点是,您不必担心有人会覆盖正在使用的变量.这对于经常使用的临时变量(例如 i j )尤其重要.

    The advantage of keeping variables within a closure is that you won't have to worry about someone overwriting the variables that you're using. This is especially important for temporary variables such as i or j that are used often.

    此模式的第二个重要部分是别名.别名允许在闭包中定义和使用变量,而无需担心变量位于哪个全局命名空间中.

    The second important part of this pattern is aliasing. Aliasing allows a variable to be defined and used within a closure without needing to worry about what global namespace it resides in.

    (function () {
        ...
        foo = window.SomeFunction(bar, baz);
        ...
    }());
    

    使用别名

    (function (sf) { //local name
        ...
        foo = sf(bar, baz);
        ...
    }(window.SomeFunction)); //global namespace
    

    这一点特别重要,因为这意味着可以通过在单个位置更改名称来更改大型JavaScript文件中的全局名称空间.这是一件好事.此外,缩小器可以将内部别名缩短为单个字母变量名称,例如 a ,从而在缩小时节省大量字节.

    This is especially important as it means that the global namespace can be changed across a large JavaScript file by changing the name in a single location. This is A Good Thing™. Additionally, minifiers can shorten the internal alias to a single letter variable name such as a, making for significant byte savings on minification.

    名称空间扩展模式取决于or运算符( || )的合并行为.在许多语言中,&& || 返回 true false ,但是在JavaScript中,& 返回第一个 falsey 值( false 0 '' null undefined )和 || 返回第一个 truthy 值(不是 falsey的任何值).对于这两个运算符,如果找不到相应的类型,则返回最后一个参数.这使得 ||| 运算符成为仅当新名称空间不存在时定义新名称的便捷方法.

    The namespace extension pattern relies on the coalescing behavior of the or operator (||). In many languages, && and || return either true or false, but in JavaScript, && returns the first falsey value (false, 0, '', null, undefined), and || returns the first truthy value (anything that's not falsey). For both operators, if the respective type is not found, the last argument is returned. This makes the || operator a convenient way of defining a new namespace only if it doesn't already exist.

    if (typeof window.Foo === 'undefined') {
        window.foo = {};
    }
    

    具有名称空间扩展名

    window.foo = window.foo || {};
    

    这很有用,因为它允许使用其他属性和方法扩展名称空间,而不必担心定义属性和方法的顺序.

    This is useful because it allows a namespace to be extended with additional properties and methods without having to worry about which order the properties and methods were defined in.

    在第一个示例中,需要在 FileB 之前执行 FileA :

    In this first example, FileA would need to be executed before FileB:

    window.foo = {};
    window.foo.bar = 'baz';
    

    FileB.js

    window.foo.fizz = 'buzz';
    

    在第二个示例中,可以按任意顺序执行 File1 File2 :

    In this second example, File1 and File2 could be executed in any order:

    window.foo = window.foo || {};
    window.foo.bar = 'baz';
    

    File2.js

    window.foo = window.foo || {};
    window.foo.fizz = 'buzz';
    

    现在在一起

    将每个模式一起使用会创建一个非常强大的模块化脚本:

    All together now

    Using each pattern together creates a very powerful modular script:

    //use foo internally so that you don't have to worry about
    //what the global namespace is called
    (function (foo) {
        //declare variables internally that you want to keep local to the script
        var i,
            len,
            internal,
            qux;
        //declare functions/properties on the alias when you want to expose them
        foo.bar = function () {...};
    //extend the global namespace so that existing extensions are persistent
    }(window.FOO = window.FOO || {}));
    

    这篇关于什么是"x = x ||"{}";JavaScript中的技巧-以及如何影响此IIFE?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆