<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
測試 javascript this 所指的 context
</body>
<script type="text/javascript">
var tmodel = (function ()
{
var myself;
var set_myself = function() {
myself = this;
};
var self;
var v1 = 'tmodel v1';
var tst = {
self: this,
fun1: function () {
console.log('tst.fun1()');
console.log(this);
console.log(this.self);
if (typeof v1 !== "undefined") {
console.log(v1);
} else {
console.log('v1 is undefined!');
}
}
};
var fun2 = function () {
console.log('tmodel.fun2()');
console.log(this);
console.log(myself);
console.log(tst.self);
if (typeof v1 !== "undefined") {
console.log(v1);
} else {
console.log('v1 is undefined!');
}
tst.fun1();
};
var fun3 = function () {
self = this;
var v1 = 'fun3 var';
console.log('tmodel.fun3()');
console.log(this);
console.log(tst.self);
if (typeof v1 !== "undefined") {
console.log(v1);
} else {
console.log('v1 is undefined!');
}
fun2();
};
/*
* fun1.this => tst
* tst.this => Window,這個不會改變
* tmodel.v1
*/
tst.fun1();
return {
set_myself: set_myself,
fun2: fun2,
fun3: fun3
}
})();
tmodel.set_myself();
/*
* fun2.this => tmodel
* 在執行 tst.fun1 中
* fun1.this => tst
*/
tmodel.fun2();
/*
* fun3.this => tmodel
* fun3.v1 => local variable
* 在執行 fun2 中
* fun2.this => Window
* 可直接存取 tmodel.v1
* 無法存取 fun3.v1
* 在執行 tst.fun1 中
* fun1.this => tst
* 可直接存取 tmodel.v1
* 無法存取 fun3.v1
*/
tmodel.fun3();
console.log('tmodel');
console.log(tmodel);
</script>
</html>
js_this_tst.php:24 tst.fun1()
js_this_tst.php:25 {self: Window, fun1: ƒ}
js_this_tst.php:26 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:28 tmodel v1
js_this_tst.php:36 tmodel.fun2()
js_this_tst.php:37 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:38 undefined
js_this_tst.php:39 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:41 tmodel v1
js_this_tst.php:24 tst.fun1()
js_this_tst.php:25 {self: Window, fun1: ƒ}
js_this_tst.php:26 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:28 tmodel v1
js_this_tst.php:52 tmodel.fun3()
js_this_tst.php:53 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:54 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:56 fun3 var
js_this_tst.php:36 tmodel.fun2()
js_this_tst.php:37 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:38 undefined
js_this_tst.php:39 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:41 tmodel v1
js_this_tst.php:24 tst.fun1()
js_this_tst.php:25 {self: Window, fun1: ƒ}
js_this_tst.php:26 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:28 tmodel v1
js_this_tst.php:74 內部執行 BEGIN
js_this_tst.php:75 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:36 tmodel.fun2()
js_this_tst.php:37 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:38 undefined
js_this_tst.php:39 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:41 tmodel v1
js_this_tst.php:24 tst.fun1()
js_this_tst.php:25 {self: Window, fun1: ƒ}
js_this_tst.php:26 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:28 tmodel v1
js_this_tst.php:52 tmodel.fun3()
js_this_tst.php:53 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:54 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:56 fun3 var
js_this_tst.php:36 tmodel.fun2()
js_this_tst.php:37 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:38 undefined
js_this_tst.php:39 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:41 tmodel v1
js_this_tst.php:24 tst.fun1()
js_this_tst.php:25 {self: Window, fun1: ƒ}
js_this_tst.php:26 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:28 tmodel v1
js_this_tst.php:78 -- 內部執行 END --
js_this_tst.php:36 tmodel.fun2()
js_this_tst.php:37 {set_myself: ƒ, fun2: ƒ, fun3: ƒ}
js_this_tst.php:38 {set_myself: ƒ, fun2: ƒ, fun3: ƒ}
js_this_tst.php:39 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:41 tmodel v1
js_this_tst.php:24 tst.fun1()
js_this_tst.php:25 {self: Window, fun1: ƒ}
js_this_tst.php:26 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:28 tmodel v1
js_this_tst.php:52 tmodel.fun3()
js_this_tst.php:53 {set_myself: ƒ, fun2: ƒ, fun3: ƒ}
js_this_tst.php:54 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:56 fun3 var
js_this_tst.php:36 tmodel.fun2()
js_this_tst.php:37 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:38 {set_myself: ƒ, fun2: ƒ, fun3: ƒ}
js_this_tst.php:39 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:41 tmodel v1
js_this_tst.php:24 tst.fun1()
js_this_tst.php:25 {self: Window, fun1: ƒ}
js_this_tst.php:26 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
js_this_tst.php:28 tmodel v1
js_this_tst.php:111 tmodel
js_this_tst.php:112 {set_myself: ƒ, fun2: ƒ, fun3: ƒ}
最需要特別注意的是,在 fun3 中呼叫 fun2,fun2 的 this 指到 Window。
為了在 tmodel 中,能夠存取自身的 context,用一個 myself 的變數來存放自身的 context。但是因為在被呼叫之前,此 object 尚未建立,因此無裡面指定 myself,只能在它的外面執行。可能有更好的解決辦法,但我目前只能找到此方法。
這是為了解決 KnockoutJS 的 computed 變數的問題。
為了在 tmodel 中,能夠存取自身的 context,用一個 myself 的變數來存放自身的 context。但是因為在被呼叫之前,此 object 尚未建立,因此無裡面指定 myself,只能在它的外面執行。可能有更好的解決辦法,但我目前只能找到此方法。
這是為了解決 KnockoutJS 的 computed 變數的問題。