mouseflowというサービスを利用して、javascriptでサイトのトラッキングをしようとしています。
javasriptを使用してsubmitを行っているページはうまくトラッキング出来ない為、下記のページを参考にして、ソースの修正を行いました。
https://mouseflow-jp.com/forms-with-no-successful-submits/
しかし、うまくトラッキングを行うことができません。
上記サービスの英語のページは、下記となります。
http://help.mouseflow.com/knowledge_base/topics/troubleshooting-forms-with-no-successful-submits
日本語のサイトであると、_mfq のオブジェクトを作成は、下記のようになっています。
javascript
1var _mfq = _mfq || [];
英語のサイトを見ると、下記のようになります。
javascript
1window._mfq = window._mfq || [];
windowsオブジェクトは、省略できるということなのですが、上記の挙動というのは全く同じということになるのでしょうか?
よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
変数宣言文
JavaScript
1window._mfq = window._mfq || [];
こちらのコードは、このコードが実行されるタイミングで window._mfq
のtruthy判定し、値を代入します。
JavaScript
1var _mfq = _mfq || [];
こちらのコードも、このコードが実行されるタイミングで _mfq
のtruthy判定して値を代入しますが、var
による変数の実体化処理が別途走ります。
var
の初期化処理は特殊で前方に遡って、undefined
で初期化するのです。
var
が記述された場所がグローバルコードならグローバルコードの先頭で変数を undefined
で初期化し、関数コードなら関数の先頭で変数をundefined
で初期化します。
詳しい使い方は下記スレッドの私の回答を読んでみて下さい。
window キーワード
window
キーワードでグローバルオブジェクトを参照できる機能は、HTML Standard によって規定されています。
しかし、全てのJavaScript実装が HTML Standard を実装しているわけではない為、JavaScript 実装によっては window
キーワードによってグローバルオブジェクトを参照できません。
そこで、ECMAScript という基本仕様に則り、キーワードを使わずにグローバルオブジェクトを参照する事で、実装依存性を無くすことが出来ます。
HTML
1<script> 2/** 3 * このコードは ES6 の module ではないグローバルコードです 4 */ 5 6'use strict'; // Strict Mode を指定します 7 8/** 9 * (1) グローバルコード 10 */ 11var global = this; // グローバルコードにおける this はグローバルオブジェクトを参照します 12 13/** 14 * (2) 関数コード1 15 */ 16(function () { 17 var global = this; // Function#call で束縛された為、グローバルコードと同じようにグローバルオブジェクトを参照出来ます 18}.call(this)); // グローバルコードからグローバルオブジェクトを引き渡します 19 20/** 21 * (3) 関数コード2 22 */ 23(function () { 24 var global = Function('return this')(); // Function() 内の関数コードはグローバルスコープで実行されます 25}()); 26</script>
Strict Mode
JavaScript には「Strict Mode」と「非Strict Mode」の二種類の実行形式が存在します。
Strict Mode を指定するには、コード中に "use strict";
を記述します。
JavaScript
1<script> // module ではない 2'use strict'; 3console.log(this); // Window (グローバルコードでは、this 値はグローバルオブジェクトを参照する) 4 5(function () { 6 console.log(this); // undefined (関数コードでは undefined を参照する) 7}()); 8</script>
非Strict Modeを指定するには、"use strict";
を記述しません。
JavaScript
1<script> // module ではない 2'use strict'; 3console.log(this); // Window (グローバルコードでは、this 値はグローバルオブジェクトを参照する) 4 5(function () { 6 console.log(this); // Window (関数コードでもグローバルオブジェクトを参照する) 7}()); 8</script>
なお、JavaScript では this
値は関数が実行されたタイミングで決定されるものであり、関数の呼び出し方によっては例外があります。
Function#call
,Function#apply
,Function#bind
- アロー関数
addEventListener
の第二引数Array#forEach
の第二引数
module (ECMAScript 6 規定)
ES6 の module を使った場合には、事情が大きく異なります。
module を使う事は質問されているコードを推奨せず、module を使ったコードを推奨する回答となります。
これは前述の私のスタンスと矛盾する為、本スレッドの別の記事で新しく回答しました。
更新履歴
- 2017/09/23 23:50 「Strict Mode」「module (ECMAScript 6 規定)」節を追加。「window キーワード」節の文面変更。
Re: gomengo さん
投稿2017/09/22 23:53
編集2017/09/23 15:14総合スコア18156
0
module (ECMAScript 6 規定)
JavaScript
1var _mfq = _mfq || [];
この書き方はグローバル変数が衝突したなら、そのまま使い、衝突しなければ配列を生成して返すコードです。
しかし、「そもそも衝突させるべきではない」という考え方も出来ます。
ECMAScript 6 では各種ライブラリの依存関係を解決する為に module が定義されました。
ブラウザにおいては、HTML Standard で定義された <script type="module">
と組み合わせる事で機能します。
JavaScript
1/** 2 * test.js 3 */ 4export const foo = 1; // 変数 foo をエクスポート 5export const bar = 'bar'; // 変数 bar をエクスポート
HTML
1<script type="module" src="test.js"></script> 2<script type="module"> 3import {foo} from './test.js'; // test.js の変数 foo をインポート 4console.log(foo); // 1 5console.log(this); // undefined (module 内の this 値は undefined) 6console.log(bar); // ReferenceError: bar is not defined (test.js 内の変数 bar はインポートしていない為、参照できない) 7</script>
名前を変えてインポート
別々のmoduleから同じ名前の変数をそのままの状態でインポートすることは出来ません。
HTML
1<script type="module"> 2import {foo} from './test1.js'; 3import {foo} from './test2.js'; // SyntaxError: Identifier 'foo' has already been declared 4</script>
別々のmoduleから同じ名前の変数をインポートするには、名前を変えてインポートします。
HTML
1<script type="module"> 2import {foo as foo1} from './test1.js'; 3import {foo as foo2} from './test2.js'; 4console.log(foo1); 5console.log(foo2); 6</script>
モジュール間のグローバルオブジェクトは共有される
モジュール間のグローバルオブジェクトは共有される為、グローバルオブジェクトを介して、データを共有する事が可能です。
が、module を使っているにも関わらず、グローバル変数で衝突させているという点で module のメリットを相殺する好ましくない書き方です。
JavaScript
1/** 2 * test1.js 3 */ 4var global = Function('return this')(), 5 fuga = 'fuga!';; 6 7global.fuga = 'fuga' in global ? global.fuga + fuga : fuga;
JavaScript
1/** 2 * test2.js 3 */ 4var global = Function('return this')(), 5 fuga = 'fuga!fuga!'; 6 7global.fuga = 'fuga' in global ? global.fuga + fuga : fuga;
HTML
1<script type="module" src="test1.js"></script> 2<script type="module" src="test2.js"></script> 3<script type="module"> 4console.log(fuga); // fuga!fuga!fuga! 5</script>
所感
raccyさんのmodule管理における問題点の指摘を受け、書きましたが、前の私の回答とはベクトルの違う回答であった為、新しく回答しました。
私としては、まだこの書き方は実装が整っていないという点で時期早々だと思いますが、最新の機能に触れておくのも悪くはないですね。
Re: gomengo さん
投稿2017/09/23 14:31
編集2017/09/23 14:37総合スコア18156
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
グローバル変数としての定義としては同じですね。
function内に記述するのであれば、windowをつけた方が安全かと思います。
下記は参考まで
投稿2017/09/23 01:55
総合スコア100
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/23 05:41
2017/09/23 06:25
2017/09/23 15:09
2017/09/23 15:44