2013-10-19 63 views
0

我是一個相對有經驗的C#(以及之前的那個C++ Win32)開發人員,我是JavaScript新手,並且有關於this指針的問題。正確使用這個指針在JavaScript中的回調knockout.js

我使用的是knockout.js,而一個名爲subscribe的函數接受一個this變量,它將在回調函數中設置。我從我的思維方式從Win32天和C#,在任何回調函數我想要一個範圍對象,其中包含我的狀態。

在這種情況下,我使用this JavaScript的東西來設置我的回調範圍。

我的問題是:

  1. 現在一切正常(full fiddle here if you are interested),但我做了什麼可怕的事情?

  2. 是否有任何理由this被用來替代明確 範圍變量作爲參數傳遞(即會使事情更容易理解爲 對我來說,這使得運作那種隱藏)。

  3. this的用途是什麼?

http://knockoutjs.com/documentation/observables.html它說:

的訂閱功能接受三個參數:回調是,每當通知發生被調用的函數,目標(可選)定義在回調函數的這個值,和事件(可選;默認爲「更改」)是要接收通知的事件的名稱。下面

myViewModel.personName.subscribe(function(oldValue) { 
    alert("The person's previous name is " + oldValue); 
}, null, "beforeChange"); 

我下面的代碼片段舉例:

var computedOptions = createComputedDepdency(viewModel[option.requires.target],option.data); 
viewModel[option.optionsName] = computedOptions; 

console.log("making callback scope object for: " + option.optionsName); 
var callbackScope = { 
    callbackName: option.optionsName, 
    options: computedOptions, 
    selectedValue: viewModel[option.selectedName] 
}; 

// when the list of available options changes, set the selected property to the first option 
computedOptions.subscribe(function() { 
    var scope = this; 
    console.log("my object: %o", scope); 
    scope.selectedValue(scope.options()[0].sku); 
    console.log("in subscribe function for..." + scope.callbackName); 
},callbackScope); 
+0

不應該'VAR範圍=本;'是回調外...? –

回答

1

首先語義注:

函數的範圍是不相關的this字。 contextthis有關。範圍與另一個函數內變量和函數的可訪問性有關。

當您嘗試讀取聲明之外的函數外的變量時,則嘗試訪問其範圍之外的變量。所以你不能這樣做,因爲var在一個範圍內,不能從當前位置訪問。

現在一切正常(如果您有興趣,請點擊此處),但是我做了些什麼可怕的事情?

如果它的工作原理,它不是那麼可怕:-)

是否有這是用來代替一個明確的範圍變量作爲參數傳遞(即會使事情更容易理解爲任何理由對我來說,這使隱藏的工作類型)。

快讀:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

在javascript中的this值由一個函數是如何被調用來確定。

從一個方面來說,這種方法可以節省討厭的上下文作爲參數:在一個有詳細記錄的庫中,this的使用非常直觀。 在其他情況下,我同意在不改變邏輯的情況下更改應用程序中的連續上下文時,可能會感到困惑。

這有什麼用途?

我們應該永遠記住javascript如何以及何時誕生。它是爲了與DOM互動而誕生的。

爲了這個目的,上下文具有根據哪個元素調用函數的變化的感覺。

例如:

var divs = document.getElementsByTagName('DIV'); 

for(var i = 0; i < divs.length; i++) { 
    divs[i].addEventListener('click',_clickHandler); 
} 

function _clickHandler() { 
    this.innerHTML = "clicked"; 
} 

DEMO http://jsfiddle.net/AYBsL/1/

這是一個例子,是如何有用以JavaScript上下文的隱式變化。

你可以爲用戶自定義功能做到這一點也:當你調用一個函數,你可以改變背景:

_clickHandler.call(divs[0]); // simulate click of first div 
0

你不應該混範圍和thisthis應該是模仿古典的oop語言,如java或++,即保持對實例對象的引用。但它只能用於在給定上下文中使用.apply().call執行任意函數。

範圍如何,您不必做任何事情就可以將範圍傳遞給函數,因爲外部範圍可以在函數內自動訪問。你應該閱讀關閉 - 這是JavaScript的最好的部分。

1

在javascript中,這個指的是調用你的函數的對象。只有在你使用'new'關鍵字的情況下,你可以指望它指向當前對象(函數)。

var MyObject = function() { 
    this.hello = function() { console.log(this); } 
} 

var instance = new MyObject(); 

有一種方法,以確保它始終是你所期望的,並且正在創造一個變量來存儲你正確的參考,並用它來代替這個......你的榜樣將是類似對此...

computedOptions = function() { 
    var that = this; 
} 

computedOptions.subscribe(function() { 
    console.log("my object: %o", scope); 
    scope.selectedValue(that.options()[0].sku); 
    console.log("in subscribe function for..." + that.callbackName); 
},callbackScope); 

MDN JavaScript reference不可避免地將它解釋得更好,然後我自己,看看它。