Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.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 ';这'/主干遗留应用程序中的作用域问题,即35; bind不是';t解算_Javascript_Backbone.js_Underscore.js - Fatal编程技术网

Javascript ';这'/主干遗留应用程序中的作用域问题,即35; bind不是';t解算

Javascript ';这'/主干遗留应用程序中的作用域问题,即35; bind不是';t解算,javascript,backbone.js,underscore.js,Javascript,Backbone.js,Underscore.js,对于一个继承下来的、有7年历史的主干网站,我有一个视图“PaymentInfoForm”,其中我需要实现一个新的小部件来处理在线支付。新的小部件(我们称之为inceptionLib)基本上是第三方UI和第四方API的验证包装器。inceptionLib是全新的、专有的,并且没有很好的文档记录,所以它是一个不透明的黑盒,但我可以在独立的演示JavaScript中很好地使用它。不过,试图与主干网整合给我带来了麻烦 inceptionLib要求我创建一个新函数inceptionLibFieldList

对于一个继承下来的、有7年历史的主干网站,我有一个视图“PaymentInfoForm”,其中我需要实现一个新的小部件来处理在线支付。新的小部件(我们称之为inceptionLib)基本上是第三方UI和第四方API的验证包装器。inceptionLib是全新的、专有的,并且没有很好的文档记录,所以它是一个不透明的黑盒,但我可以在独立的演示JavaScript中很好地使用它。不过,试图与主干网整合给我带来了麻烦

inceptionLib要求我创建一个新函数inceptionLibFieldListener,作为PaymentInfoForm视图的一部分,以处理用户与小部件交互时的状态更改。在这个函数中,我需要做的是能够设置视图的几个属性。我对“this”关键字有问题。我知道当在内部函数中使用“this”时,我的视图失去了作用域,但我不确定为什么会发生这种情况(除非它与黑盒子中的某些东西有关!)。如果我试图将我的函数包装在u.bind中,作为该类型问题的常见解决方案,“this”将成为对窗口对象的引用,就好像它在对象模型中向上“跳过一个级别”。我不知道如何强制“this”成为我的视图,就像在下一个函数中一样,这样我就可以从这里修改我的视图属性

感觉像是inceptionLib在劫持“这个”,好吧,我真的需要它回来!谢谢你的帮助

App.PaymentInfoForm = Backbone.View.extend({ // existing view

    oldProperty1: null, // existing property
    myNewProperty2: null, // new property that I need to modify from inceptionLibFieldListener()

    initialize: function (){...}, // create objects & stuff, doesn't matter

    render: function(){ // render, including putting the inceptionLib widget on the page
        {...}
        var inceptionLibForm = inceptionLib.createForm();
        var that = this;
        vgsForm.initInceptionLib().then(function(){
            inceptionLibForm.renderCreditCard('#cc-container', that.inceptionLibFieldListener); 
            inceptionLibForm.renderExpirationDate('#exp-container', that.inceptionLibFieldListener);
        })
        return this;
    },  

    inceptionLibFieldListener: function(newState, prevState, flags) { // inceptionLib listener function
        console.log(this); // result is output for the inceptionLib object
    },
    
    // if I change the inceptionLibFieldListener to this:
    inceptionLibFieldListener: _.bind(function(newState, prevState, flags) { // _.bind should fix it
        console.log(this); // but result is Window object
    // }, this),
    
    somethingElse: function(){ // unrelated function just to test the difference in 'this' 
        console.log(this); // result is console output for the view, as expected
    },
    
    ...

您的问题源于对
的工作原理的误解。我不会详细解释
这个
,因为MDN对这个主题有一个明确的定义。但是,我可以简单地解释为什么您的代码不工作以及如何修复它

当你这样做的时候

var=this;
vgsForm.initInceptionLib().then(函数(){
inceptionLibForm.renderCreditCard(“#cc container”,即.inceptionLibFieldListener);
inceptionLibForm.renderExpirationDate(“#exp container”,that.inceptionLibFieldListener);
})
确保从
PaymentInfoForm
实例获得
inceptionLibFieldListener
,这是您尝试实现的一半。但是,执行
x.aMethod
不会将
aMethod
绑定到
x
。换句话说,当运行
aMethod
时,
this
仍然可以是任何东西。下面的代码演示了这一点:

var x={
方法:函数(){
console.log(this.approperty);
},
财产:1
};
变量y={
物业:2
};
var-aMethod=x.aMethod;//函数正确但不受约束
aMethod();//未定义的打印
方法。呼叫(y);//印刷品2
x、 aMethod();//印刷品1
您可能想知道,在上一个示例中,
aMethod
似乎绑定到了
x
。为什么
x.aMethod()
起作用,但不
aMethod=x.aMethod;aMethod()
?为什么您不总是需要调用
aMethod.call(x)
?这是因为JavaScript引擎将
x.aMethod(a,b,c)
识别为特例,并自动将其转换为
x.aMethod.call(x,a,b,c)
。你可能会发现这是违反直觉的,你会有一个观点,但这正是JS的工作方式

当你这样做的时候

inceptionLibFieldListener:u.bind(函数(newState、prevState、flags){/u.bind应该修复它
console.log(this);//但结果是窗口对象
},本页)
问题在于
在任何函数上下文之外进行计算<代码>全局范围内的此
始终是ES6模块范围内的
窗口
对象,或
未定义
。因此,
.bind
正在做它应该做的事情,但是您传递给它的
this
是错误的

有两件事可以解决这个问题。第一个选项是在更合适的时候使用
.bind
,当
确实具有您需要的值时,例如在
渲染
方法中:

var-boundInceptionFieldListener=979;.bind(this.inceptionLibFieldListener,this);
vgsForm.initInceptionLib().then(函数(){
renderCreditCard('cc container',boundInceptionFieldListener);
inceptionLibForm.renderExpirationDate(“#exp container”,boundInceptionFieldListener);
})
另一个选项是使用,它永久性地将方法更改为始终绑定到您的
PaymentInfoForm
实例。这是您可以在
构造函数
初始化
方法中执行的操作,但如果您还希望以未绑定形式使用该方法,我不建议您这样做:

\uuu.bindAll(这是“inceptionLibFieldListener”);
使用后一种方法,现有的
渲染
代码应按原样工作