Javascript实例变量显示为未定义

时间:2014-11-18 14:50:43

标签: javascript jquery oop

我创建了一个Javascript对象,它将一个点击监听器添加到某些类上,然后依次调用PHP函数从MYSQL / PHP驱动的后端生成结果。 后端工作正常(结果正确返回)。我遇到一个问题,即实例认为实例的属性(字符串)为空,即使我已经将值直接赋给该属性。

这是我的代码:

//Workout Videos Class
var Workout = function(offset, limit, element, categoryId) {
    this.offset = offset;
    this.html = "";
    this.limit = limit;
    this.element = element;
    this.categoryId = categoryId
    var self = this;

    jQuery(this.element).on("click", function(e) {
        e.preventDefault();
        self.seeMoreClick(this, self.videoCallBack, self)
    });
}

Workout.prototype.seeMoreClick = function(item, videoCallBack, thisArg) {
    jQuery.ajax({
        type      :   'POST',
        dataType  :   'json',
        url       :   'api/get-videos',
        data      :   'category_id=' + this.categoryId + "&offset=" + this.offset + "&limit=" + this.limit,
        success   : function(data) {
            videoCallBack.call(thisArg, data, item);
        }
    });
}

Workout.prototype.videoCallBack = function(response, item) {
    this.offset = response.offset;
    if(response.videos) {   
        jQuery(response.videos).each(function(key, video) {                     
            this.html += "<div class='col-md-4' data-related-video='" + video.videoId + "'>";
                this.html += '<a href="#" class="dashboard-video"></a>';
                this.html += '<div class="video-information">';
                    this.html += '<h5 class="tk-bebas-neue">' + video.videoName + '</h5>';
                    this.html += '<p>' + video.videoDesc + '</p>';
                    this.html += '<p>Equipment: ';
                    jQuery(video.equipment).each(function(equipKey, equipmentItem) {
                        this.html += '<a href="#" class="equipment-item" data-equipment-id="' + equipmentItem.equipmentId + '">' + equipmentItem.equipmentName + '</a>';
                    });
                    this.html += "</p>";
                    this.html += '<div class="video-rating" data-rel="' + video.videoId + '" data-user-id="' + video.userId + '">'; 


                    this.html += "</div>";
                this.html += '</div>';
            this.html += "</div>";              
        });
    } else {
        this.html += "<div class='col-md-12'>No more videos to show</div>";
    }
    console.log(this.html);
    jQuery("#" + jQuery(this.element).attr("data-related") + " .col-md-8").append(this.html);
}

我遇到的问题是'videoCallBack'函数,我将其用于传递给AJAX函数,以确保它在所有代码运行之前解析。当我在设置后直接在控制台中登录时,'this.html'属性显示为空。谁能明白为什么会发生这种情况? 感谢

3 个答案:

答案 0 :(得分:3)

这是this更改代码的结果。在forEach块&#39; this&#39;指的是一个不同的对象,因此您将所有HTML添加到完全不同的对象中。

一个简单的解决方法是保存对此的引用:

Workout.prototype.videoCallBack = function(response, item) {
    var self = this;
    self.offset = response.offset;
    if(response.videos) {   
        jQuery(response.videos).each(function(key, video) {                     
            self.html += "<div class='col-md-4' data-related-video='" + video.videoId + "'>";
           ...

答案 1 :(得分:2)

当你执行函数时,你需要注意this的值,因为它会根据函数的调用方式而改变。它永远不会自动从其封闭的环境中继承。

因此,在您的情况下,传递给.each()的回调的this值与外部环境不同。您需要绑定this值或将其存储在变量中并引用回调中的变量。

要绑定它,您可以使用$.proxy()

 // -----------------------------v
jQuery(response.videos).each($.proxy(function(key, video) {   

    this.html += "<div class='col-md-4' data-related-video='" + video.videoId + "'>";
    // ...and so on...       

}, this));
//   ^

或现代浏览器中的原生.bind()方法。

jQuery(response.videos).each(function(key, video) {   

    this.html += "<div class='col-md-4' data-related-video='" + video.videoId + "'>";
    // ...and so on...       

}.bind(this));
//  ^

这两个函数都将返回一个新函数,其this值永久绑定到您提供的值。这避免了必须将另一个变量添加到封闭范围。

答案 2 :(得分:1)

因为您没有访问权利&#39;这个&#39;。 在你的每个职能范围内,另一个&#39;这个&#39;存在。 通过设置变量

来避免这种情况
var self = this;

并使用它来保留您的上下文。

this.html to self.html