Вопрос по javascript – Как охватить пространство имен javascript несколькими файлами?

5

Я игнорировал JavaScript навсегда. Я начал использовать JQuery несколько лет назад, чтобы я мог обойтись. Но так как я начал больше заниматься TDD, я решил вчера по-настоящему погрузиться в javascript (и, возможно, coffeescript после этого).

В моем приложении ASP.NET Web Forms у меня много страниц, и в настоящее время большинство из них не содержат тонны JavaScript. Я в процессе изменения этого. Я использую Жасмин с Chutzpah для создания моих тестов.

Я двигался вместе с прохождением тестов, как и ожидалось. Но затем я хотел создать пространство имен, чтобы не растоптать все глобальное пространство.

После прочтения этой статьи: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

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

У меня есть папка с именем / Scripts. В этой папке находятся некоторые фреймворки, которые я использую, такие как jQuery, jasmine, (twitter) bootstrap и modernizr. У меня также есть подпапка / Site, где я размещаю свой код для сайта в нескольких файлах на основе страницы. (product.js, billing.js и т. д.)

В / Scripts / Site я добавил подпапку в / Tests (или Specs), в которой есть файлы (product_test.js, billing_tests.js и т. Д.).

Не имея пространства имен, все в порядке. У меня есть файл utility.js, который я создал сpadLeft вспомогательная функция. Затем я использовал этот глобальный padLeft в другом файле .js. Мои тесты все работали, и я был счастлив. Затем я решил выяснить пространство имен и изменил свой Scripts / Site / utility.js так:

<code>(function (myns, $, undefined) {
    //private property
    var isSomething = true;

    //public property
    myns.something = "something";

    //public method
    myns.padLeft = function (str, len, pad) {
        str = Array(len + 1 - str.length).join(pad) + str;

        return str;
    };


    //check to see if myns exists in global space
    //if not, assign it a new Object Literal
}(window.myns= window.myns|| {}, jQuery ));
</code>

Тогда в моих скриптах / сайте / тестах / utility_test.js у меня есть

<code>/// <reference path="../utility.js" />

describe("Namespace myns with public property something", function () {
    it("Should Equal 'something'", function () {
        expect(myns.something).toEqual('something');
    });
});
</code>

В этом чрезвычайно простом тесте я ожидал, что myns.something вернется со строковым значением «что-то».

Это не так. Возвращаетсяundefined.

So, how do I to use javascript namespace across multiple files?

Извините за длинное вступление, но я подумал, что это может помочь объяснитьwhy я делаю это таким образом. Я также изложил все это, потому что я открыт для того, чтобы выслушать идеи о том, как эта установка полностью неправильна или частично неправильна или что-то еще.

Спасибо, что нашли время, чтобы прочитать этот вопрос.

UPDATE: SOLVED Спасибо за вашу помощь. Большая помощь пришла от комментатора @ T.J. Crowder. Я не знал, что инструмент jsbin существует, и, убедившись, что приведенный выше код был вставлен в инструмент, и результаты были правильными, я понял, что в моей среде что-то должно быть отключено.

Ссылка в принятом ответе также очень мне помогла. После того, как синтаксис и логика были согласованы и работали, мне просто нужно было определить, что не так в моей настройке. Мне стыдно сказать, что я перешел в jQuery, но в своем тестовом окружении, где я пытался заставить это работать, я на самом деле не использовал jQuery. Это означало, что модуль фактически не загружался, поэтому myns никогда не устанавливался.

Спасибо всем. Надеюсь, это может быть полезно для кого-то в будущем. Если вы используете вышеупомянутое, убедитесь, что вы включили объект jQuery. Другой вариант - не передавать jQuery и не удалять $ из списка параметров.

спасибо за длинное вступление, это помогает нам понять, что вы хотите :-) Philipp
@ T.J.Crowder Спасибо. Это мусорное ведро работает, но я не могу понять, почему оно отличается в моей среде. Я не знал о jsbin, так что спасибо за это! Я собираюсь попробовать несколько вещей в этой песочнице. Chad Carter
То, что вы показали, должно работать при условииutility.js а такжеutility_test.js включены, и в этом порядке. Пример:jsbin.com/idofog T.J. Crowder
Вот действительно хорошая статья о шаблоне модуля (то, что вы здесь используете), посвященная его реализации в файлах:adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth Keith Rousseau

Ваш Ответ

2   ответа
1

myns = window.myns || {};
(function(myns, $, undefined) {
    ...
}(myns, jQuery));

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

Спасибо, я попробовал, но у меня были те же результаты. Похоже, я что-то еще напутал. Копаться в этом ... Chad Carter
0

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

window.myns.something

Первая функция уже добавляет ваш объект к объекту окна, а объект окна доступен из любого места.

@PhilippMehrwald Спасибо. Мне следовало бы более четко заявить «эмуляция пространств имен». С шаблоном, который я использую после того, как я пытаюсь избежать использования window.myns.something. Даже изменить его в моем тестовом файле не удалось. Поэтому у меня должно быть что-то еще не так. Спасибо! Chad Carter
Где мыс изначально определен?
Я знаю, но, как вы сказали, он "эмулирует" Пространства имен. Существуют огромные различия в пространствах имен, например в .NET, но это похоже на объекты в .NET (за исключением изменения интерфейса во время выполнения)
использование такого вложенного свойства является распространенным способом эмуляции пространств имен в Javascript.
@PhilippMehrwald в настоящее время определено в Script \ utilities.js внизу первого блока кода: window.myns = window.myns || {}, Chad Carter

Похожие вопросы