0

采取以下代码:

function animateTo(parent) {
    this.parent = $('#' + parent);
    console.log(this.parent)
    this.animator = function () {
        this.parent.animate({
            scrollTop: 5
        }, 5);
    }
}
test = new animateTo('data');
test.animator;

第一个console.log在控制台中显示了完整的对象,但是当我尝试运行时this.parent.animate出现错误:

Uncaught TypeError: Object [object global] has no method 'animate' animator.js:60
(anonymous function

谁能解释这是为什么?我试过this.parent.selector了,我得到了正确的结果,但是如果我尝试调用 animate 方法,我会得到那个错误。

4

2 回答 2

1

You should learn a little more about scope in JavaScript. The short version is: each time you open a new function, you create a new scope. Your code paste shows two nested scopes, where this in the inner scope does not match this in the outer scope.

Anyway, the solution is simple because you don't even need to use this in your scenario

function animateTo(parent){
  var $parent = $('#' + parent);
  console.log($parent)

  this.animator = function(){
    $parent.animate({scrollTop: 5}, 5);
  };
}

var test = animateTo('data');
test.animator;

It almost seems like you're trying to do something like this though.

The following is opinion for how I would write this code

var Animator = function(selector) {
  this.parent = $(selector);
};

Animator.prototype.animate = function() {
  this.parent.animate({scrollTop: 5}, 5);
};

Usage would look like this

var test = new Animator("#data");
test.animate();
于 2013-08-20T22:50:06.650 回答
1

你应该做:

function animateTo(parent){
    this.parent = $('#' + parent);
    var that = this;
    this.animator = function(){
        that.parent.animate({scrollTop:5},5);
    }
}

或者

function animateTo(parent){
    return {
        parent: $('#' + parent),
        animator: function(){
            this.parent.animate({scrollTop:5},5);
        }
    }
}

如果您不喜欢这两个选项中的任何一个,则始终可以使用bind,但除非您不关心旧浏览器,否则您必须使用 shim。

例如(在现代浏览器中):

function animateTo(parent){
    this.parent = $('#' + parent);
    this.animator = (function(){
        this.parent.animate({scrollTop:5},5);
    }).bind(this)
}

或使用下划线或 lodash:

function animateTo(parent){
    this.parent = $('#' + parent);
    this.animator = _.bind(function(){
        this.parent.animate({scrollTop:5},5);
    }, this)
}

顺便说一句,习惯上将构造函数大写,因为它们被视为类型(如基于类的面向对象语言中的类)。

于 2013-08-20T22:46:02.880 回答