Skip to content

Instantly share code, notes, and snippets.

@haiiro-shimeji
Last active December 17, 2015 07:59
Show Gist options
  • Select an option

  • Save haiiro-shimeji/5576792 to your computer and use it in GitHub Desktop.

Select an option

Save haiiro-shimeji/5576792 to your computer and use it in GitHub Desktop.
#js #tddjs
var hoge_ScopeTest = 1001, fuga_ScopeTest = 1002, piyo_ScopeTest = 1003, foo_ScopeTest = 1004;
TestCase("Scope Test", {
"test scope": function () {
var sum = function() {
//関数内部で宣言されたローカル変数は先頭で宣言されたのと同義になる(=ホイスト)
//var i, total;
assertUndefined(i); //宣言前でもアクセスできる、キモい!
assertException(function() {
//でも宣言のない変数はしっかりアクセスできない、キモい!!
assertUndefined(someVar);
}, "ReferenceError");
var total = arguments[0];
if (arguments.length > 1) {
for (var i = 1; arguments.length > i; ++i) {
total += arguments[i];
}
}
//ブロックスコープは存在しない
assertEquals(arguments.length, i);
return total;
}
assertEquals(15, sum(1,2,3,4,5));
},
"test closure scope": function() {
var hoge_ScopeTest = 101;
var fuga_ScopeTest = 102;
var piyo_ScopeTest = 103;
(function() {
var hoge_ScopeTest = 11;
var fuga_ScopeTest = 12;
(function() {
var hoge_ScopeTest = 1;
//解決順序はローカル変数→ 自由変数→ グローバル変数
assertEquals(1, hoge_ScopeTest);
assertEquals(12, fuga_ScopeTest);
assertEquals(103, piyo_ScopeTest);
assertEquals(1004, foo_ScopeTest);
//function created by Function() does'nt behave as closure
var func = Function("assertEquals(1001, hoge_ScopeTest)");
func();
}());
}());
},
"test of wrong for usage": function() {
var funcs = [];
var results = [1, 2, 3, 4]
for (var i in results) {
funcs[i] = function() {
return results[i];
};
}
//こうなってほしいがそうはならない
//assertEquals(1, funcs[0]());
//assertEquals(2, funcs[1]());
//assertEquals(3, funcs[2]());
//assertEquals(4, funcs[3]());
assertEquals(4, funcs[0]());
assertEquals(4, funcs[1]());
assertEquals(4, funcs[2]());
assertEquals(4, funcs[3]());
},
"test of each": function() {
//クロージャでスコープを制限してやれば期待した動作になる
//each関数の作成が有効
var each = function(a, callback) {
for (var n in a) {
callback.call(null, n, a[n]);
}
};
var funcs = [];
var results = [1, 2, 3, 4]
each(results, function(n, v) {
funcs[n] = function() {
return results[n];
};
});
assertEquals(1, funcs[0]());
assertEquals(2, funcs[1]());
assertEquals(3, funcs[2]());
assertEquals(4, funcs[3]());
}
});
function func2() {
return this;
}
TestCase("This Test", {
"test of this": function() {
var obj = {
hoge: 3,
func: function() {
return this.hoge;
}
};
assertEquals(3, obj.func());
var obj2 = {
hoge: 8,
func: obj.func
};
assertEquals(8, obj2.func());
//this は呼び出し元となったオブジェクトを指す.
//メソッドがどのオブジェクトのメンバかは関係ない.
assertEquals(13, obj.func.call({ hoge: 13 }));
var func = function() {
return 2*this.hoge;
}
assertEquals(34, func.call({ hoge: 17 }));
//呼び出し元のオブジェクトがない場合はグローバルオブジェクトがthisになる.
assertEquals(
(function() {
return this;
}()),
window
);
//関数宣言でも同じ
assertEquals(func2(), window);
assertEquals(
(Function("return this"))(),
window
);
},
"call method from primitive value": function() {
//ECMAScript5ではプリミティブ値をthisとすることができる.
assertEquals(
5,
(function() {
return this
}).call(5)
);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment