Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript原型绑定_Javascript_Prototype_Bind - Fatal编程技术网

JavaScript原型绑定

JavaScript原型绑定,javascript,prototype,bind,Javascript,Prototype,Bind,我不熟悉基于原型的语言,读过这个问题: 我想知道使用基于原型的签名将方法附加到对象有什么价值。为什么不在对象的定义中将方法附加到对象的属性 其次,当使用原型签名定义对象上的方法时,“this”指针为什么解析到函数中的窗口对象?这似乎是一个设计缺陷。如果不是,有人能解释一下,或者给我一个关于为什么不的解释吗 多谢各位 编辑: 此代码按预期执行,呈现一个包含单词“here”的消息框 function Obj() { this.theVar = 'here'; this.met

我不熟悉基于原型的语言,读过这个问题:

我想知道使用基于原型的签名将方法附加到对象有什么价值。为什么不在对象的定义中将方法附加到对象的属性

其次,当使用原型签名定义对象上的方法时,“this”指针为什么解析到函数中的窗口对象?这似乎是一个设计缺陷。如果不是,有人能解释一下,或者给我一个关于为什么不的解释吗

多谢各位

编辑:

此代码按预期执行,呈现一个包含单词“here”的消息框

function Obj() {   
    this.theVar = 'here';
    this.method2 = function(){ alert( this.theVar ); }
}

Obj.prototype.method3 = function(){ this.method2(); }
Obj.prototype.method4 = function(){ this.method3(); }

var obj = new Obj();
obj.method4();
这段代码是我的AJAX回调,“This”指针在执行期间指向“window”对象

Test.prototype.nextCallback = function( response ) {
    if( response.Status != 'SUCCESS' )
        show_message( response.Message, false );
    else
        this.setQuestion( response.Question );
}

Test.prototype.setQuestion = function( question ){ ... }
“this”指针实际上在AJAX调用之前工作正常,但在调用之后工作不正常。这是因为在AJAX调用返回之后和调用回调之前,
nextCallback()
上下文没有正确恢复吗?有办法补救吗

  • 在JavaScript中,如果使用函数作为构造函数来创建新对象,那么在构造函数中为
    this
    分配一个方法意味着每个新对象都定义了一个新方法。分配给原型意味着您只能在原型中获得方法的一个定义

  • 是的,
    这个
    在某些情况下指向全局对象是一个设计缺陷,但我不认为在您提到的情况下会发生这种情况

  • 如果您想了解JavaScript对象和原型继承方面的最佳实践,请观看

  • 在JavaScript中,如果使用函数作为构造函数来创建新对象,那么在构造函数中为
    this
    分配一个方法意味着每个新对象都定义了一个新方法。分配给原型意味着您只能在原型中获得方法的一个定义

  • 是的,
    这个
    在某些情况下指向全局对象是一个设计缺陷,但我不认为在您提到的情况下会发生这种情况


  • 如果您想了解JavaScript对象和原型继承方面的最佳实践,请注意。

    1-在构造函数原型上添加成员的要点是行为重用

    从该原型继承的所有对象实例将能够通过原型链解析成员,并且成员仅定义一次,而不是在每个实例中

    2-发生这种情况是因为每个函数都有自己的执行上下文(存储
    This
    值的位置),调用函数时会隐式设置
    This
    值,如果函数引用没有基本对象(例如
    foo();
    ,vs
    obj.foo()
    ),全局对象将在调用的方法中设置为
    这个

    有关详细信息,请参见的第二部分

    Edit:查看代码后,似乎您正在传递
    nextCallback
    方法的引用作为某个Ajax成功事件的回调函数,如果是这样,引用的基本对象将丢失,通常的方法是使用正确调用方法的匿名函数,例如:

    var obj = new Test();
    //...
    someAjaxLib(url, function (data) {
      obj.nextCallback(data); // `this` will refer to obj within nextCallback
    });
    
    function Test() {
      var instance = this; // store reference to the current instance
    
      this.nextCallback = function( response ) {
        if( response.Status != 'SUCCESS' ) {
          show_message( response.Message, false );
        } else {
          instance.setQuestion( response.Question ); // use the stored reference
        }
      }
    }
    
    另一种方法是将方法绑定到构造函数中的实例,请记住,该方法将被定义为您创建的每个对象实例上的自有属性,而不会被继承,例如:

    var obj = new Test();
    //...
    someAjaxLib(url, function (data) {
      obj.nextCallback(data); // `this` will refer to obj within nextCallback
    });
    
    function Test() {
      var instance = this; // store reference to the current instance
    
      this.nextCallback = function( response ) {
        if( response.Status != 'SUCCESS' ) {
          show_message( response.Message, false );
        } else {
          instance.setQuestion( response.Question ); // use the stored reference
        }
      }
    }
    

    1-在构造函数原型上添加成员的要点是行为重用

    从该原型继承的所有对象实例将能够通过原型链解析成员,并且成员仅定义一次,而不是在每个实例中

    2-发生这种情况是因为每个函数都有自己的执行上下文(存储
    This
    值的位置),调用函数时会隐式设置
    This
    值,如果函数引用没有基本对象(例如
    foo();
    ,vs
    obj.foo()
    ),全局对象将在调用的方法中设置为
    这个

    有关详细信息,请参见的第二部分

    Edit:查看代码后,似乎您正在传递
    nextCallback
    方法的引用作为某个Ajax成功事件的回调函数,如果是这样,引用的基本对象将丢失,通常的方法是使用正确调用方法的匿名函数,例如:

    var obj = new Test();
    //...
    someAjaxLib(url, function (data) {
      obj.nextCallback(data); // `this` will refer to obj within nextCallback
    });
    
    function Test() {
      var instance = this; // store reference to the current instance
    
      this.nextCallback = function( response ) {
        if( response.Status != 'SUCCESS' ) {
          show_message( response.Message, false );
        } else {
          instance.setQuestion( response.Question ); // use the stored reference
        }
      }
    }
    
    另一种方法是将方法绑定到构造函数中的实例,请记住,该方法将被定义为您创建的每个对象实例上的自有属性,而不会被继承,例如:

    var obj = new Test();
    //...
    someAjaxLib(url, function (data) {
      obj.nextCallback(data); // `this` will refer to obj within nextCallback
    });
    
    function Test() {
      var instance = this; // store reference to the current instance
    
      this.nextCallback = function( response ) {
        if( response.Status != 'SUCCESS' ) {
          show_message( response.Message, false );
        } else {
          instance.setQuestion( response.Question ); // use the stored reference
        }
      }
    }
    

    在我的例子中,当通过原型签名将该方法添加到对象中,并随后作为AJAX回调方法传递使用时,该方法的作用域将被重新限定到全局对象(窗口),并丢失其原始上下文。也就是说,该方法不再是定义它的原型的成员


    我只在Firefox中测试过这个。我猜这种行为是因为AJAX调用是在不同的OS线程上物理执行的,从AJAX调用返回时,会找到并执行指定的回调方法。未尝试在线程之间解析方法的原始上下文。同样,这只是一个猜测。

    在我的例子中,当该方法通过原型签名添加到一个对象中,并随后作为AJAX回调方法传递使用时,该方法将被重新限定到全局对象(窗口)的范围,并丢失其原始上下文。也就是说,该方法不再是定义它的原型的成员

    我只在Firefox中测试过这个。我猜这种行为是因为AJAX调用是在不同的OS线程上物理执行的