雖然這個問題發生在我專門用KnockoutJS,我的問題更像是一個一般的JavaScript問題。爲什麼在Javascript中,這個上下文基於調用方式而改變?
然而,理解ko.observable()和ko.observableArray()會返回一個方法,所以當爲它們賦值時,您需要調用目標爲方法而不是簡單地爲它們賦值。我正在使用的代碼還應該支持普通對象和數組,我爲什麼需要解析爲調用方法來爲目標分配值。
想到這些2個例子:
非工作(在此上下文中調用的方法改變):
// Assigning value to the target object
var target;
// target can be of any of thr following types
target = ko.observableArray(); // knockout observable array (function)
// target = ko.observable(); // knockout observable (function)
// target = {}; // generic object
// target = []; // generic array
//#region resolve method to call
var method;
if (isObservable(target)) {
// if it is a knockout observable array, we need to call the target's push method
// if it is a konckout observable, we need to call the target as a method
method = target.push || target;
} else {
// if target is a generic array, we need to use the array's push prototype
// if target is a generic object, we need to wrap a function to assign the value
method = target.push || function(item){ target = item; };
}
//#endregion
// call resolved method
method(entity);
工作(在此上下文中精細):
if (isObservable(target)) {
if (target.push) {
target.push(entity);
} else {
target(entity);
};
} else {
if (target.push) {
target.push(entity);
} else {
target = entity;
};
}
現在,以實際問題:
在第一種方法中,稍後在執行鏈中使用基因敲除可觀察基因敲除時,指的是this
內部的上下文,試圖訪問observable本身(即在有人想知道的情況下使用this.t())。在這種特殊情況下,由於callin的方式,this
已更改爲window
對象,而不是指向原始可觀察對象。
在後一種情況下,淘汰賽的this
上下文正常。
你們任何一個JavaScript大師都能告訴我,我的調用方式可以改變被調用函數的'this'上下文嗎?
好吧,我知道有人想小提琴所以這裏去:)
Method 1 (Uncaught TypeError: Object [object global] has no method 'peek')
附:我沒有試圖修復代碼,我試圖理解爲什麼我的代碼更改了this
上下文。
UPDATE:
感謝您的快速解答!當我不知道爲什麼(特別是如何)發生某些事情時,我必須說我討厭它。從你的答案I fiddled up this quick fiddle到攝製的情況,我想我現在知道了:)
// So having an object like Foo
function Foo() {
this.dirThis = function() {
console.dir(this);
};
};
// Instantiating a new Foo
var foo = new Foo();
// Foo.dirThis() has it's original context
foo.dirThis(); // First log in console (Foo)
// The calling code is in Window context
console.dir(this); // Second log in console (Window)
// Passing a reference to the target function from another context
// changes the target function's context
var anotherFoo = foo.dirThis;
// So, when being called through anotherFoo,
// Window object gets logged
// instead of Foo's original context
anotherFoo(); // 3rd log
// So, to elaborate, if I create a type AnotherFoo
function AnotherFoo(dirThis){
this.dirThis = dirThis;
}
// And and instantiate it
var newFoo = new AnotherFoo(foo.dirThis);
newFoo.dirThis(); // Should dir AnotherFoo (4th in log)
你問爲什麼?這是因爲這是語言設計的方式。 「context」('this'的值)是根據函數的調用方式設置的,就像你在標題中描述的一樣。 –
這個答案包含有關'this'如何在JavaScript中工作的一個很好的解釋:http://stackoverflow.com/a/134149/1443358 –
這是非常長的囉嗦;你應該發佈**最短的**例子來重現你的問題,在這種情況下,它將大約兩行代碼。 – meagar