代码之家  ›  专栏  ›  技术社区  ›  Carson Myers

“this”在javascript类方法中未定义

  •  53
  • Carson Myers  · 技术社区  · 14 年前

    我不熟悉JavaScript。就我所真正做的来说,它是新的,修改了现有的代码,并编写了少量的jquery。

    现在我正试图用属性和方法编写一个“类”,但是我在方法方面遇到了问题。我的代码:

    function Request(destination, stay_open) {
        this.state = "ready";
        this.xhr = null;
        this.destination = destination;
        this.stay_open = stay_open;
    
        this.open = function(data) {
            this.xhr = $.ajax({
                url: destination,
                success: this.handle_response,
                error: this.handle_failure,
                timeout: 100000000,
                data: data,
                dataType: 'json',
            });
        };
    
        /* snip... */
    
    }
    
    Request.prototype.start = function() {
        if( this.stay_open == true ) {
            this.open({msg: 'listen'});
        } else {
    
        }
    };
    //all console.log's omitted
    

    问题是,在 Request.prototype.start , this 未定义,因此if语句的计算结果为false。我在这里做错什么了?

    3 回复  |  直到 8 年前
        1
  •  53
  •   Chetan S    14 年前

    如何调用start函数?

    这应该管用( 新的 是关键

    var o = new Request(destination, stay_open);
    o.start();
    

    如果你直接这样称呼它 Request.prototype.start() , this 将引用全局上下文( window 在浏览器中)。

    此外,如果 未定义,将导致错误。if表达式的计算结果不为false。

    更新 : 对象不是根据声明设置的,而是由 调用 . 它的意思是,如果将函数属性赋给类似 x = o.start 并打电话 x() , 内部开始不再引用 o . 当你这样做的时候 setTimeout . 要使其工作,请执行以下操作:

     var o = new Request(...);
     setTimeout(function() { o.start(); }, 1000);
    
        2
  •  15
  •   xj9    14 年前

    Javascript的OOP有点古怪(或者很多),需要一些适应。你首先要记住的是 没有课 从课程的角度思考会让你很困惑。为了使用附加到构造函数(相当于类定义的javascript)的方法,需要实例化对象。例如:

    Ninja = function (name) {
        this.name = name;
    };
    aNinja = new Ninja('foxy');
    aNinja.name; //-> 'foxy'
    
    enemyNinja = new Ninja('boggis');
    enemyNinja.name; //=> 'boggis'
    

    注意 Ninja 实例具有相同的属性,但 aNinja 无法访问的属性 enemyNinja . (这部分应该非常简单/直接)当您开始向 prototype :

    Ninja.prototype.jump = function () {
       return this.name + ' jumped!';
    };
    Ninja.prototype.jump(); //-> Error.
    aNinja.jump(); //-> 'foxy jumped!'
    enemyNinja.jump(); //-> 'boggis jumped!'
    

    直接调用此函数将引发错误,因为 this 当构造函数被实例化时,只指向正确的对象(“类”)(否则它指向全局对象, window 在浏览器中)

        3
  •  4
  •   Nitin    8 年前

    在ES2015 A.K.A ES6中, class 是对 functions .

    如果要强制设置 this 你可以使用 bind() 方法。正如@chetan指出的那样,调用时也可以设置上下文!请检查以下示例:

    class Form extends React.Component {
    constructor() {
        super();
      }
      handleChange(e) {
        switch (e.target.id) {
          case 'owner':
            this.setState({owner: e.target.value});
            break;
          default:
        }
      }
      render() {
        return (
          <form onSubmit={this.handleNewCodeBlock}>
            <p>Owner:</p> <input onChange={this.handleChange.bind(this)} />
          </form>
        );
      }
    }
    

    在这里,我们把上下文放在里面 handleChange() Form .