2010-02-12 5 views
7

У меня есть класс JavaScript, который выглядит следующим образом:Сфера «это» в JavaScript

function SomeFunction() 
{ 
    this.doSomething(function() 
    { 
     this.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Этот код выдает ошибку, потому что объем «это» внутри функции, которая передается в DoSomething() является отличается от объема «этого» вне этой функции.

Я понимаю, почему это так, но каков наилучший способ справиться с этим? Это то, что я делаю:

function SomeFunction() 
{ 
    var thisObject = this; 

    this.doSomething(function() 
    { 
     thisObject.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Это прекрасно работает, но это просто похоже на хак. Просто интересно, есть ли у кого-то лучший способ.

+2

@Jon Kruger Это то, что я тоже делаю. Я думаю, что это нормально. Вы можете изменить 'this' на' call' и 'apply', но это не всегда соответствует тому, что вы делаете хорошо. Другой вариант - это параметр 'this' как параметр, но это похоже на еще больший взлом. –

+0

@Jonathon Что вы подразумеваете под «Вы можете изменить это с помощью вызова и применить»? –

+1

@Jon Kruger Посмотрите это, посмотрите также свою статью для 'call': https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply –

ответ

10

Это правильное и общепринятое обходное решение. Это своего рода kludgy, но это то, что делают все. Обычно эта дополнительная переменная называется self, как:

function SomeFunction() 
{ 
    var self = this; 

    this.doSomething(function() 
    { 
     self.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 
+1

Имейте в виду, что 'self' является свойством объекта window в браузерах, который указывает на себя, хотя это вряд ли вызовет какие-либо проблемы. –

+0

Другие имена, которые я видел, используются довольно много: 'that' и' me', в зависимости от контекста. – cHao

3

this имеет динамический "сферу". Это означает, что он настроен на то, что связывает его, а this связан «вызовом метода». То есть, любое время в вашей программе вы видите это: w.f() то время как f выполняется, this динамически связан с f, даже еслиf был this в лексической области.

Большинство инфраструктур JavaScript предоставляют некоторые возможности для решения этой проблемы. С Prototype.js (например), вы можете сделать это:

this.doSomething(function() { this.doSomethingElse(); }.bind(this)); 

Ваш «взломать», однако, хорошо. Обычно я делаю (function (self) { ... })(this) вокруг любых функций, в которых мне нужна лексически скопированная переменная this.

1

Также стоит упомянуть, что следующая версия ECMAScript (спецификация языка для JavaScript) собирается ввести Function.bind(), что позволит вам указать постоянный контекст для функции.

Смежные вопросы