file теги - Как включить файл JavaScript в другой файл JavaScript?




вызов подгрузка (25)

Есть ли что-то в JavaScript, подобное @import в CSS, которое позволяет вам включать файл JavaScript в другой файл JavaScript?


Answers

Лучше использовать способ jQuery . Чтобы задержать готовое событие, сначала вызовите $.holdReady(true). Пример ( source ):

$.holdReady(true);
$.getScript("myplugin.js", function() {
    $.holdReady(false);
});

На современном языке это было бы

function loadJs( url ){
  return new Promise( resolve => {
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    document.head.appendChild( script );
  });
}

Если ваше намерение загрузить файл JavaScript использует функции из импортированного / включенного файла , вы также можете определить глобальный объект и задать функции как объекты объекта. Например:

global.js

A = {};

file1.js

A.func1 = function() {
  console.log("func1");
}

file2.js

A.func2 = function() {
  console.log("func2");
}

main.js

A.func1();
A.func2();

Вам просто нужно быть осторожным, когда вы включаете скрипты в файл HTML. Порядок должен быть следующим:

<head>
  <script type="text/javascript" src="global.js"></script>
  <script type="text/javascript" src="file1.js"></script>
  <script type="text/javascript" src="file2.js"></script>
  <script type="text/javascript" src="main.js"></script>
</head>

Этот скрипт добавит файл JavaScript в начало любого другого <script>тега:

(function () {
    var li = document.createElement('script'); 
    li.type = 'text/javascript'; 
    li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"; 
    li.async=true; 
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(li, s);
})();

Возможно динамическое создание тега JavaScript и добавление его в HTML-документ из другого кода JavaScript. Это загрузит целевой файл JavaScript.

function includeJs(jsFilePath) {
    var js = document.createElement("script");

    js.type = "text/javascript";
    js.src = jsFilePath;

    document.body.appendChild(js);
}

includeJs("/path/to/some/file.js");

Существует также Head.js . С этим очень легко справиться:

head.load("js/jquery.min.js",
          "js/jquery.someplugin.js",
          "js/jquery.someplugin.css", function() {
  alert("Everything is ok!");
});

Как вы видите, это проще, чем Require.js и так же удобно, как $.getScriptметод jQuery . Он также имеет некоторые дополнительные функции, такие как условная загрузка, обнаружение функций и многое другое .


import находится в ECMAScript 6.

Синтаксис

import name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import name , { member [ , [...] ] } from "module-name";
import "module-name" as name;

Вместо того, чтобы включать во время выполнения, используйте сценарий для конкатенации перед загрузкой.

Я использую Sprockets (я не знаю, есть ли другие). Вы создаете свой код JavaScript в отдельных файлах и включаете комментарии, которые обрабатываются движком Sprockets, в том числе. Для разработки вы можете включать файлы последовательно, затем для их слияния ...

Смотрите также:


Это должно сделать:

xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);

Если кто-то ищет что-то более продвинутое, попробуйте RequireJS . Вы получите дополнительные преимущества, такие как управление зависимостями, лучший параллелизм и избегайте дублирования (т. Е. Извлекаете сценарий несколько раз).

Вы можете писать свои файлы JavaScript в «modules», а затем ссылаться на них как на зависимости в других сценариях. Или вы можете использовать RequireJS как простое решение «get get this script».

Пример:

Определить зависимости как модули:

некоторые-dependency.js

define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {

     //Your actual script goes here.   
     //The dependent scripts will be fetched if necessary.

     return libraryObject;  //For example, jQuery object
});

implementation.js - ваш «основной» JavaScript-файл, который зависит от some-dependency.js

require(['some-dependency'], function(dependency) {

    //Your script goes here
    //some-dependency.js is fetched.   
    //Then your script is executed
});

Выдержка из GitHub README:

RequireJS загружает простые файлы JavaScript, а также более определенные модули. Он оптимизирован для использования в браузере, в том числе в Web Worker, но его можно использовать в других средах JavaScript, таких как Rhino и Node. Он реализует API асинхронного модуля.

RequireJS использует теги обычного сценария для загрузки модулей / файлов, поэтому он должен обеспечивать легкую отладку. Его можно использовать просто для загрузки существующих файлов JavaScript, поэтому вы можете добавить его в свой существующий проект, не переписывая файлы JavaScript.

...


Возможно, вы можете использовать эту функцию, которую я нашел на этой странице. Как включить файл JavaScript в файл JavaScript? :

function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';

    head.appendChild(script)
}

У меня была простая проблема, но я был озадачен ответами на этот вопрос.

Мне пришлось использовать переменную (myVar1), определенную в одном файле JavaScript (myvariables.js) в другом файле JavaScript (main.js).

Для этого я сделал следующее:

Загрузите код JavaScript в файл HTML в правильном порядке, сначала myvariables.js, затем main.js:

<html>
    <body onload="bodyReady();" >

        <script src="myvariables.js" > </script>
        <script src="main.js" > </script>

        <!-- Some other code -->
    </body>
</html>

Файл: myvariables.js

var myVar1 = "I am variable from myvariables.js";

Файл: main.js

// ...
function bodyReady() {
    // ...
    alert (myVar1);    // This shows "I am variable from myvariables.js", which I needed
    // ...
}
// ...

Как вы видели, я использовал переменную в одном файле JavaScript в другом файле JavaScript, но мне не нужно было включать ее в другую. Мне просто нужно было убедиться, что первый файл JavaScript загружен до второго файла JavaScript, а переменные первого файла JavaScript доступны во втором файле JavaScript автоматически.

Это спасло мой день. Надеюсь, это поможет.


Другой способ, который, на мой взгляд, намного чище, состоит в том, чтобы сделать синхронный запрос Ajax вместо использования <script> . Это также относится к Node.js

Вот пример использования jQuery:

function require(script) {
    $.ajax({
        url: script,
        dataType: "script",
        async: false,           // <-- This is the key
        success: function () {
            // all good...
        },
        error: function () {
            throw new Error("Could not load script " + script);
        }
    });
}

Затем вы можете использовать его в своем коде, как обычно, используйте include:

require("/scripts/subscript.js");

И иметь возможность вызывать функцию из требуемого скрипта в следующей строке:

subscript.doSomethingCool(); 

Я создал функцию, которая позволит вам использовать схожие формулировки с C # / Java для включения файла JavaScript. Я тестировал его немного даже изнутри другого файла JavaScript и, похоже, работает. Это требует jQuery, хотя для немного «магии» в конце.

Я поместил этот код в файл в корень моего каталога сценариев (я его назвал global.js, но вы можете использовать все, что захотите. Если я не ошибаюсь, это и jQuery должны быть единственными необходимыми сценариями на данной странице. в значительной степени непроверен за пределами некоторого базового использования, поэтому могут быть или не быть какие-либо проблемы с тем, как я это сделал, использовать на свой страх и риск yadda yadda Я не несу ответственности, если вы ввернете что-нибудь в yadda yadda:

/**
* @fileoverview This file stores global functions that are required by other libraries.
*/

if (typeof(jQuery) === 'undefined') {
    throw 'jQuery is required.';
}

/** Defines the base script directory that all .js files are assumed to be organized under. */
var BASE_DIR = 'js/';

/**
* Loads the specified file, outputting it to the <head> HTMLElement.
*
* This method mimics the use of using in C# or import in Java, allowing
* JavaScript files to "load" other JavaScript files that they depend on
* using a familiar syntax.
*
* This method assumes all scripts are under a directory at the root and will
* append the .js file extension automatically.
*
* @param {string} file A file path to load using C#/Java "dot" syntax.
*
* Example Usage:
* imports('core.utils.extensions');
* This will output: <script type="text/javascript" src="/js/core/utils/extensions.js"></script>
*/
function imports(file) {
    var fileName = file.substr(file.lastIndexOf('.') + 1, file.length);

    // Convert PascalCase name to underscore_separated_name
    var regex = new RegExp(/([A-Z])/g);
    if (regex.test(fileName)) {
        var separated = fileName.replace(regex, ",$1").replace(',', '');
        fileName = separated.replace(/[,]/g, '_');
    }

    // Remove the original JavaScript file name to replace with underscore version
    file = file.substr(0, file.lastIndexOf('.'));

    // Convert the dot syntax to directory syntax to actually load the file
    if (file.indexOf('.') > 0) {
        file = file.replace(/[.]/g, '/');
    }

    var src = BASE_DIR + file + '/' + fileName.toLowerCase() + '.js';
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;

    $('head').find('script:last').append(script);
}

Вот синхронная версия без jQuery :

function myRequire( url ) {
    var ajax = new XMLHttpRequest();
    ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
    ajax.onreadystatechange = function () {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4) {
            switch( ajax.status) {
                case 200:
                    eval.apply( window, [script] );
                    console.log("script loaded: ", url);
                    break;
                default:
                    console.log("ERROR: script not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

Обратите внимание, что для получения этого рабочего кросс-домена серверу необходимо будет установить заголовок allow-origin в своем ответе.


Для вас есть хорошая новость. Очень скоро вы сможете легко загрузить код JavaScript. Он станет стандартным способом импорта модулей кода JavaScript и будет частью самого основного JavaScript.

Вам просто нужно написать import cond from 'cond.js'; для загрузки макроса с именем cond из файла cond.js

Таким образом, вам не нужно полагаться на какие-либо рамки JavaScript, и вам не нужно явно делать вызовы Ajax .

Ссылаться на:


Мой обычный метод:

var require = function (src, cb) {
    cb = cb || function () {};

    var newScriptTag = document.createElement('script'),
        firstScriptTag = document.getElementsByTagName('script')[0];
    newScriptTag.src = src;
    newScriptTag.async = true;
    newScriptTag.onload = newScriptTag.onreadystatechange = function () {
        (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') && (cb());
    };
    firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag);
}

Он отлично работает и не использует никаких перезагрузок страниц для меня. Я пробовал метод AJAX (один из других ответов), но он не работает так хорошо для меня.

Вот объяснение того, как код работает для любопытных: по существу, он создает новый тег сценария (после первого) URL-адреса. Он устанавливает его в асинхронный режим, поэтому он не блокирует остальную часть кода, но вызывает обратный вызов, когда readyState (состояние загружаемого содержимого) изменяется на «загружен».


Я написал простой модуль, который автоматизирует работу по импорту / включая скрипты модулей в JavaScript. Подробное объяснение кода см. В блоге, в котором должны быть указаны модули require / import / include .

// ----- USAGE -----

require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');

ready(function(){
    //Do something when required scripts are loaded
});

    //--------------------

var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
                                                   //the root directory of your library, any library.


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };
    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

_.rmod = namespaceToUri = function(script_name, url) {
    var np = script_name.split('.');
    if (np.getLast() === '*') {
        np.pop();
        np.push('_all');
    }

    if(!url)
        url = '';

    script_name = np.join('.');
    return  url + np.join('/')+'.js';
};

//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
    var uri = '';
    if (script_name.indexOf('/') > -1) {
        uri = script_name;
        var lastSlash = uri.lastIndexOf('/');
        script_name = uri.substring(lastSlash+1, uri.length);
    } 
    else {
        uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
    }

    if (!_rmod.loading.scripts.hasOwnProperty(script_name)
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri,
            _rmod.requireCallback,
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.push(fn);
};

Если вы используете веб-работников и хотите включить дополнительные сценарии в сферу действия рабочего, другие ответы, связанные с добавлением скриптов в head тег и т. Д., Не будут работать для вас.

К счастью, у веб-рабочих есть своя функция importScripts которая является глобальной функцией в рамках Web Worker, родной самому браузеру, поскольку она является частью спецификации .

В качестве альтернативы, в качестве второго наиболее высоко RequireJS ответа на ваш вопрос подчеркивается , RequireJS также может обрабатывать в том числе скрипты внутри Web Worker (вероятно, сам вызов importScripts , но с несколькими другими полезными функциями).


var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

На этот вопрос есть много потенциальных ответов. Мой ответ, очевидно, основан на некоторых из них. Это то, что я закончил, прочитав все ответы.

Проблема с $.getScriptи действительно любое другое решение, требующее обратного вызова при загрузке, завершено в том, что если у вас несколько файлов, которые его используют и зависят друг от друга, у вас больше нет возможности узнать, когда загружены все сценарии (когда они вложены в нескольких файлах).

Пример:

file3.js

var f3obj = "file3";

// Define other stuff

file2.js:

var f2obj = "file2";
$.getScript("file3.js", function(){

    alert(f3obj);

    // Use anything defined in file3.
});

file1.js:

$.getScript("file2.js", function(){
    alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
    alert(f2obj);

    // Use anything defined in the loaded script...
});

Вы правы, когда говорите, что можете указать Ajax для синхронного запуска или использования XMLHttpRequest , но текущая тенденция, как представляется, заключается в том, чтобы отклонять синхронные запросы, поэтому вы не можете получить полную поддержку браузера сейчас или в будущем.

Вы можете попытаться использовать $.whenмассив отложенных объектов, но теперь вы делаете это в каждом файле, и файл2 будет считаться загруженным, как только он $.whenбудет выполнен не тогда, когда выполняется обратный вызов, так что файл1 продолжает выполнение до того, как будет загружен файл3 , Это по-прежнему имеет ту же проблему.

Я решил вернуться назад, а не вперед. Благодарю вас document.writeln. Я знаю, что это табу, но до тех пор, пока оно используется правильно, это хорошо работает. Вы получаете код, который легко отлаживается, отображается в DOM правильно и может гарантировать правильность загрузки зависимостей.

Конечно, вы можете использовать $ («body»). Append (), но тогда вы больше не можете отлаживать корректно.

ПРИМЕЧАНИЕ. Вы должны использовать это только во время загрузки страницы, иначе вы получите пустой экран. Другими словами, всегда размещайте это перед / за пределами document.ready . Я не тестировал это после того, как страница загружена в событие щелчка или что-то в этом роде, но я уверен, что она потерпит неудачу.

Мне понравилась идея расширения jQuery, но, очевидно, вам это не нужно.

Перед вызовом document.writelnон проверяет, чтобы сценарий еще не загружался, оценивая все элементы сценария.

Я предполагаю, что сценарий не выполнен полностью до document.readyтех пор, пока его событие не будет выполнено. (Я знаю, что использование document.readyне требуется, но многие люди используют его, и обработка этого является защитой.)

Когда дополнительные файлы загружаются, document.readyобратные вызовы будут выполнены в неправильном порядке. Чтобы решить эту проблему, когда сценарий загружен, скрипт, который импортировал его, повторно импортирован сам и выполнение остановлено. Это приводит к тому, что исходный файл теперь document.readyвыполняет обратный вызов после любого из любых импортируемых им скриптов.

Вместо этого подхода вы можете попытаться изменить jQuery readyList, но это казалось худшим решением.

Решение:

$.extend(true,
{
    import_js : function(scriptpath, reAddLast)
    {
        if (typeof reAddLast === "undefined" || reAddLast === null)
        {
            reAddLast = true; // Default this value to true. It is not used by the end user, only to facilitate recursion correctly.
        }

        var found = false;
        if (reAddLast == true) // If we are re-adding the originating script we do not care if it has already been added.
        {
            found = $('script').filter(function () {
                return ($(this).attr('src') == scriptpath);
            }).length != 0; // jQuery to check if the script already exists. (replace it with straight JavaScript if you don't like jQuery.
        }

        if (found == false) {

            var callingScriptPath = $('script').last().attr("src"); // Get the script that is currently loading. Again this creates a limitation where this should not be used in a button, and only before document.ready.

            document.writeln("<script type='text/javascript' src='" + scriptpath + "'></script>"); // Add the script to the document using writeln

            if (reAddLast)
            {
                $.import_js(callingScriptPath, false); // Call itself with the originating script to fix the order.
                throw 'Readding script to correct order: ' + scriptpath + ' < ' + callingScriptPath; // This halts execution of the originating script since it is getting reloaded. If you put a try / catch around the call to $.import_js you results will vary.
            }
            return true;
        }
        return false;
    }
});

Использование:

file3:

var f3obj = "file3";

// Define other stuff
$(function(){
    f3obj = "file3docready";
});

File2:

$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
    f2obj = "file2docready";
});

File1:

$.import_js('js/file2.js');

// Use objects from file2 or file3
alert(f3obj); // "file3"
alert(f2obj); // "file2"

$(function(){
    // Use objects from file2 or file3 some more.
    alert(f3obj); //"file3docready"
    alert(f2obj); //"file2docready"
});

На самом деле есть способ загрузить файл JavaScript не асинхронно, поэтому вы можете использовать функции, включенные в ваш загруженный файл, сразу после его загрузки, и я думаю, что он работает во всех браузерах.

Вам нужно использовать jQuery.append() в элементе <head> вашей страницы, то есть:

$("head").append('<script type="text/javascript" src="' + script + '"></script>');

Однако этот метод также имеет проблему: если в импортированном файле JavaScript произошла ошибка, Firebug (а также Firefox Error Console и инструменты разработчика Chrome ) также сообщают о своем месте неправильно, что является большой проблемой, если вы используете Firebug для отслеживания Ошибок JavaScript много (я). По какой-то причине Firebug просто не знает о недавно загруженном файле, поэтому, если в этом файле произошла ошибка, он сообщает, что он произошел в вашем основном HTML файле, и у вас возникнут проблемы с поиском истинной причины ошибки.

Но если это не проблема для вас, тогда этот метод должен работать.

Я на самом деле написал плагин jQuery с именем $ .import_js (), который использует этот метод:

(function($)
{
    /*
     * $.import_js() helper (for JavaScript importing within JavaScript code).
     */
    var import_js_imported = [];

    $.extend(true,
    {
        import_js : function(script)
        {
            var found = false;
            for (var i = 0; i < import_js_imported.length; i++)
                if (import_js_imported[i] == script) {
                    found = true;
                    break;
                }

            if (found == false) {
                $("head").append('<script type="text/javascript" src="' + script + '"></script>');
                import_js_imported.push(script);
            }
        }
    });

})(jQuery);

Итак, все, что вам нужно будет сделать для импорта JavaScript:

$.import_js('/path_to_project/scripts/somefunctions.js');

Я также сделал простой Example этого Example .

Он включает файл main.js в основном HTML, а затем скрипт в main.js использует $.import_js() для импорта дополнительного файла с именем included.js , который определяет эту функцию:

function hello()
{
    alert("Hello world!");
}

И сразу после включения included.js вызывается функция hello() , и вы получаете предупреждение.

(Этот ответ отвечает на комментарий e-satis).


@importСинтаксис для достижения CSS-как JavaScript импортирования можно с помощью такого инструмента, как смеси через их особый .mixтип файла (см here ). Я полагаю, что приложение просто использует один из вышеупомянутых методов, хотя я не знаю.

Из документации по .mixфайлам Mixture :

Файлы Mix - это файлы .js или .css с .mix. в имени файла. Микс-файл просто расширяет функциональность обычного стиля или файла сценария и позволяет импортировать и комбинировать.

Вот пример .mixфайла, который объединяет несколько .jsфайлов в один:

// scripts-global.mix.js
// Plugins - Global

@import "global-plugins/headroom.js";
@import "global-plugins/retina-1.1.0.js";
@import "global-plugins/isotope.js";
@import "global-plugins/jquery.fitvids.js";

Смесь выводит это как, scripts-global.jsа также как сокращенную версию ( scripts-global.min.js).

Примечание. Я никоим образом не связан с Mixture, кроме использования его в качестве средства разработки на начальном этапе. Я столкнулся с этим вопросом, увидев .mixфайл JavaScript в действии (в одном из шаблонов Mixture) и немного смущенный им («вы можете это сделать?» Подумал я про себя). Затем я понял, что это тип файла приложения (несколько разочаровывающий, согласованный). Тем не менее, полагал, что знание может быть полезным для других.

UPDATE : смесь теперь бесплатна (офлайн).

UPDATE : смесь прекращается. Старые выпуски смеси по-прежнему доступны


Большинство приведенных здесь решений подразумевают динамическую загрузку. Я искал вместо этого компилятор, который собирал все зависящие файлы в один выходной файл. То же, что и препроцессоры Less / Sass @import с CSS @import at-rule. Поскольку я не нашел ничего подходящего в этом роде, я написал простой инструмент для решения проблемы.

Итак, вот компилятор https://github.com/dsheiko/jsic , который надежно заменяет $import("file-path") запрошенным файлом. Вот соответствующий плагин Grunt : https://github.com/dsheiko/grunt-jsic .

На главной ветви jQuery они просто объединяют файлы исходного кода в один, начиная с intro.js и заканчивая outtro.js . Это меня не устраивает, поскольку он не обеспечивает гибкости при разработке исходного кода. Посмотрите, как это работает с jsic:

SRC / main.js

var foo = $import("./Form/Input/Tel");

ЦСИ / Форма / вход / Tel.js

function() {
    return {
          prop: "",
          method: function(){}
    }
}

Теперь мы можем запустить компилятор:

node jsic.js src/main.js build/mail.js

И получить объединенный файл

строить / main.js

var foo = function() {
    return {
          prop: "",
          method: function(){}
    }
};

Закрытие очень похож на объект. Он создается при каждом вызове функции.

Объем закрытия в JavaScript является лексическим, что означает, что все, что содержится в функции, к которой принадлежит замыкание , имеет доступ к любой переменной, которая в ней.

Переменная содержится в закрытии, если вы

  1. назначьте его var foo=1; или же
  2. просто пиши var foo;

Если внутренняя функция (функция, содержащаяся внутри другой функции) обращается к такой переменной, не определяя ее в своей собственной области с помощью var, она изменяет содержимое переменной во внешнем закрытии .

Закрытия переживет выполнения функции, породившей его. Если другие функции выходят из замыкания / области действия, в которой они определены (например, как возвращаемые значения), они будут продолжать ссылаться на это закрытие .

пример

function example(closure) {
  // define somevariable to live in the closure of example
  var somevariable = 'unchanged';

  return {
    change_to: function(value) {
      somevariable = value;
    },
    log: function(value) {
      console.log('somevariable of closure %s is: %s',
        closure, somevariable);
    }
  }
}

closure_one = example('one');
closure_two = example('two');

closure_one.log();
closure_two.log();
closure_one.change_to('some new value');
closure_one.log();
closure_two.log();

Выход

somevariable of closure one is: unchanged
somevariable of closure two is: unchanged
somevariable of closure one is: some new value
somevariable of closure two is: unchanged




javascript file import include