2012-01-11 3 views
3

У меня есть 2 блока кода, один из которых не работает, и тот, который работает, потому что я назначаю это = this и использую его в своей функции вместо этого. Может кто-нибудь помочь мне понять, почему это так. Это помогло бы узнать, как нужно думать о доступе к переменным в функциях в объектах в JavaScript и о характере «этого», если я говорю это правильно (если нет, пожалуйста, просветите меня). Спасибо!Понимание «этого» в Javascript

var add = function (x, y) { 
    return x + y; 
    } 

var myObject = { 
    value: 0, 
    increment: function (inc) { 
    this.value += typeof inc === 'number' ? inc : 1; 
    } 
}; 

myObject.double2 = function() { 
    // var that = this; 

    var helper = function() { 
    this.value = add(this.value, this.value) 
    }; 

    helper(); 
}; 

myObject.increment(100); 
document.writeln(myObject.value); // Prints 100 
myObject.double2(); 
document.writeln('<BR/>'); // Prints <BR/> 
document.writeln(myObject.value); // Prints 100, **FAILS** 

И модифицированный код:

var add = function (x, y) { 
    return x + y; 
    } 

var myObject = { 
    value: 0, 
    increment: function (inc) { 
    this.value += typeof inc === 'number' ? inc : 1; 
    } 
}; 

myObject.double2 = function() { 
    var that = this; 

    var helper = function() { 
    that.value = add(that.value, that.value) 
    }; 

    helper(); 
}; 

myObject.increment(100); 
document.writeln(myObject.value); // Prints 100 
myObject.double2(); 
document.writeln('<BR/>'); // Prints <BR/> 
document.writeln(myObject.value); // Prints 200 - **NOW IT WORKS** 
+0

'this' относится к локальному контексту выполнения. (Я на 100% уверен, что кто-то еще может сказать это лучше меня.) Ваша переменная 'that' - это закрытие, которое фиксирует значение' this', так что вы можете ссылаться на него внутри вызова функции, когда это происходит, в какой-то момент в будущем. – asawyer

ответ

4

Первый не работает, потому что, когда каждая функция this зависит от того, как она была вызвана.

Сначала вы делаете myObject.double2() и поэтому this = myObject. Но внутри double2 вы вызываете helper() сам по себе, и нет объекта, на который вы его вызываете (это не myObject.helper()). Таким образом, this по умолчанию ссылается на объект global (или window объект в браузере).

Во втором примере вы «взяли» ссылку на myObject (that=this=myObject) и так that.value=myObject.value.

+0

спасибо! Это очень четкое описание и имеет смысл для меня. – zallarak

2

Я думаю, что это link бы в значительной степени помочь вам понять различия объекта и частных пользователей в Javascript для решения вашей проблемы, пожалуйста, посмотрите на Частный раздел. Надеюсь, поможет!

+0

Я предполагаю, что вы забыли ссылку – xbonez

+0

Спасибо за ваш комментарий, я не вижу вашу ссылку, хотя – zallarak

+0

это на слово «ссылка» – Skuld

1

Mozilla имеет хорошее представление об этом. Если вы хотите, чтобы это работало без присвоения this до that, вы всегда можете использовать call.

Пример: jsfiddle.net/5azde/

+0

tx для ссылки и кода примера. – zallarak

0

И вы всегда можете помнить об этом:

Когда функция объекта называется, объект будет передан в качестве этого значения (в случае 'add' и 'increment', которые относятся к 'window' и 'myObject' отдельно). И если функция не принадлежит к каким-либо объектам, в качестве этого значения будет передаваться окно (или глобальное) (как в случае с вспомогательным элементом функции в вашем примере кода).

И я рад видеть вопрос о чистом js. Нет jQuery, No css, No dom selector. ха-ха.

Может быть, это помогает. :-)

+0

и обратите внимание, что каждое значение этой функции определяется и неизменяется при формировании функции. Но вы можете изменить это значение с помощью функции «вызов» или «применить». – trinity

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