19.08.2012, 11:49
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
Доступ к свойству внутри метода.
Здравствуйте.
Вопрос: что я не так делаю?
Кусочек кода, содержащий только значимое для вопроса:
var Paradise = {
state: "inactive",
paradiseLost: function(){
function AddActiveMarker(index,obj){
console.log(obj.state)
}
AddActiveMarker(0,this)
}
}
свойство state успешно меняется другой функцией.
Значение этого свойства нужно использовать в функции AddActiveMarker().
Внутри функции paradiseLost() это свойство читается нормально, но во вложенную функцию передать не могу, получаю undefined.
Где чего недопонимаю?
Заранее спасибо.
|
|
19.08.2012, 12:00
|
Профессор
|
|
Регистрация: 16.05.2011
Сообщений: 307
|
|
var Paradise = {
state: "inactive",
paradiseLost: function(){
function AddActiveMarker(index,obj){
alert(obj.state)
}
AddActiveMarker(0,this)
}
}
Paradise.state=90;
Paradise.paradiseLost()//90
__________________
Я только учусь.Ногами просьба не бить
|
|
19.08.2012, 12:26
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
bot87, спасибо за ответ.
То есть, код корректен и всё должно работать?
Тем не менее у меня сейчас в консоль валится вот такая ошибка: Uncaught TypeError: Cannot read property 'state' of undefined.
Может быть в мою выдержку из кода не попало что-то существенное. Только учусь, ещё могу даже не понимать, где может быть ошибка.
Вот код объекта полностью:
var Paradise = Backbone.View.extend({
el: $("#paradise"),
model: appState,
state: "inactive",
animateDuration: 400,
animateDelay: 400,
initialize: function(){
this.model.bind('change:frame', this.onFrameChange, this)
},
onFrameChange: function(){
var cFrame = this.model.get("frame")
switch (true) {
case (cFrame>15 && cFrame<25):
var ff = (25-cFrame)/20*Math.PI
$(this.el).css({opacity:Math.cos(ff)}).show()
break
case(cFrame>48 && cFrame<56):
var ff = (cFrame-48)/16*Math.PI
$(this.el).css({opacity:Math.cos(ff)}).show()
break
case(cFrame>=25 && cFrame<=48):
$(this.el).css({opacity:1}).show()
if(cFrame>=30 && this.state=="inactive"){
this.state="boom"
this.paradiseBoom()
}else if(cFrame<30 && this.state=="boom"){
this.paradiseLost()
this.state="inactive"
}
break
default:
$(this.el).hide()
this.paradiseLost()
this.state="inactive"
}
},
paradiseBoom: function(){
var $happiness = $(this.el).children("li")
var animateDuration = this.animateDuration
var animateDelay = this.animateDelay
function AddActiveMarker(index,obj){
var $cHappiness = $happiness.eq(index)
if($cHappiness.size()==1){
$("#eden").show()
switch(index){
case 0:
$("#tree")
.css({opacity:0,display:"block"})
.animate({opacity:1},{duration:animateDuration})
break
case 1:
$("#mrpostman")
.css({opacity:0,display:"block"})
.animate({opacity:1},{duration:animateDuration})
break
case 2:
$("#bench")
.css({opacity:0,display:"block"})
.animate({opacity:1},{duration:animateDuration})
break
}
$("<span class=activemarker />")
.css({opacity:0})
.appendTo($cHappiness).animate({opacity:1},{duration:animateDuration,complete:function(){
if(obj.state=="boom") setTimeout(function(){AddActiveMarker(index+1,obj)},animateDelay)
}})
}
}
AddActiveMarker(0,this)
},
paradiseLost: function(){
$(this.el).children("li").children("span.activemarker").remove()
$("#eden").animate({opacity:0},{duration:400,complete:function(){
$(this).hide().css({opacity:1})
$("#eden>*").hide()
}})
}
})
var paradise = new Paradise()
В консоли ошибка указывает на эту строку: if(obj.state=="boom") setTimeout(function(){AddActiveMarker(index+1,obj) },animateDelay)
|
|
19.08.2012, 13:16
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
LittlePony, для начала вам надо понять:
1. что такое this ( если уж совсем по простому),
2. как передавать нужный вам this
var Paradise = {
state: "inactive",
paradiseLost: method
};
function method() {
alert( this === Paradise );
}
Paradise.paradiseLost(); // true
method.call( Paradise ) // true
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Последний раз редактировалось nerv_, 19.08.2012 в 13:26.
|
|
19.08.2012, 20:35
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
Большое спасибо за эту ссылку на статью. Статья открыла глаза на многое, бывшее до этого непонятным.
Однако нет, this не становится window. Если сделать
console.log(this)
, то в консоли пишется:
Код:
|
d
$el: p.fn.p.init[1]
cid: "view4"
el: HTMLUListElement
options: Object
state: "boom"
__proto__: x |
что, собственно, и ожидалось. Свойство state у этого объекта есть и правильно читается. Но если внутри функции AddActiveMarker() написать
console.log(obj)
, то в консоли пишется:
Код:
|
Uncaught TypeError: Cannot read property 'state' of undefined init.js:219
Backbone.View.extend.paradiseBoom.$.css.appendTo.animate.complete init.js:219
p.speed.d.complete jquery.js:2
p.Callbacks.k jquery.js:2
p.Callbacks.l.fireWith jquery.js:2
i jquery.js:2
p.fx.tick |
и вот это уже мне совершенно непонятно.
|
|
19.08.2012, 20:54
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Сообщение от LittlePony
|
Однако нет, this не становится window. Если сделать
|
внутри обработчика события, повешанного на элемент DOM c помощью квери, this ссылается на этот элемент.
AddActiveMarker.call( Paradise, 0, Paradise );
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
|
|
19.08.2012, 21:33
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
Сообщение от nerv_
|
внутри обработчика события, повешанного на элемент DOM c помощью квери, this ссылается на этот элемент.
AddActiveMarker.call( Paradise, 0, Paradise );
|
nerv_, большое спасибо на внимание и помощь. Но пока результат тот же.
А ещё мне бы хотелось не только добиться работоспособности, но и понять, как это всё работает.
Так вот, если я правильно понимаю, то между записями
AddActiveMarker.call( Paradise, 0, Paradise );
и
AddActiveMarker( 0, Paradise );
разница только та, что в первом случае мы явно указываем, что будет скрываться под this внутри этой функции при таком вызове. Но нигде внутри этой функции this не используется. Тогда в чём смысл такой замены?
|
|
19.08.2012, 21:51
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Сообщение от LittlePony
|
Тогда в чём смысл такой замены?
|
мне показалось по первому примеру смысл был.
Сейчас еще раз посмотрел твой код. Як у тебя там все наворочено и точек с запятыми не хватает )
Смотри, если проблема здесь,
AddActiveMarker(0,this)
ищи, что такое этот this и откуда он передается
Еще есть "секретный" способ сделать правильный this
function Constructor() {
var self = this;
self.method = function() { };
}
var cat = new Constructor();
вроде твой случай
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Последний раз редактировалось nerv_, 19.08.2012 в 21:54.
|
|
19.08.2012, 22:01
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
Сообщение от nerv_
|
мне показалось по первому примеру смысл был.
Сейчас еще раз посмотрел твой код. Як у тебя там все наворочено и точек с запятыми не хватает )
|
Это разве наворочено? Это только малая часть кода, только один из объектов. Если интересно, могу потом, когда будет готово, показать результат. А точек с запятыми где не хватает?
Сообщение от nerv_
|
Смотри, если проблема здесь,
AddActiveMarker(0,this)
ищи, что такое этот this и откуда он передается
|
Нет, проблема не здесь, проверено. Если прямо перед этим вызовом функции поставить console.log(this), то выводится то, что и ожидается.
Но если даже сразу в этой функции первой строкой поставить вывод того, что в неё передалось, то выводится совершенно неожиданный результат.
Сообщение от nerv_
|
Еще есть секретный способ сделать правильный this
function Constructor() {
var self = this;
self.method = function() { };
}
var cat = new Constructor();
вроде твой случай
|
А вот это непонятно. Можешь объяснить или послать, где почитать о таком?
|
|
|
|