我的代码非常简单。对我来说它应该有用。
var preview = WinJS.Class.define(
function (el, options) {
el.winControl = this;
this.el = el;
this.textarea = d.getElementById('preview-input');
this.preview = d.getElementById('preview-text');
this.form = d.getElementById('perview-form');
this.preview.addEventListener('click', this.click, false);
//WinJS.Utilities.query("button", this.form)
//this.preview.addEventListener('', this.save, false);
},
{
click: function (e) {
this.form.style('display', 'block');
}
}
);
WinJS.Namespace.define('RegCtrl', { preview: preview });
但是当发生点击时this.form
似乎未定义为null。为什么?我不想在类的每个方法中初始化对象。
我做了一个非常小的额外测试
var preview = WinJS.Class.define(
function (el, options) {
var test = 1;
this.test = 1;
this.test1();
},
{
test1: function () {
console.log(this.form, test);
}
}
); WinJS.Namespace.define(' RegCtrl',{preview:preview});
此测试在第this.test1();
行失败。我现在认为这个类叫RegCtrl.preview()
而不是new RegCtrl.preview()
。
如何在这个名为new
但不是简单函数的函数内部进行修改?
答案 0 :(得分:3)
其他答案并未解释发生了什么,因此提供的建议不正确。
JavaScript具有一流的函数对象 - 您可以将它们作为值传递。这正是您在设置此回调时所做的事情:
this.preview.addEventListener('click', this.click, false);
您正在获取this.click属性的内容,该属性恰好是一个函数,并将其交给addEventListener函数以执行它想要的任何操作。
我对那里的术语非常具体 - 注意我特意说 function ,而不是 method 。 JavaScript并没有真正的方法构造,它只是将方法作为对象的属性。
那么"这个"会员来自哪里?它是在呼叫者处确定的 - 您在'左侧使用的对象。是一个成为这个价值的人。例如,
function exampleFunc() { console.log("this.myName = " + this.myName); }
var a = { myName: "Chris", doSomething: exampleFunc };
var b = { myName: "Bob", doSomething: exampleFunc };
注意我已经为doSomething属性分配了完全相同的功能。会发生什么:
a.doSomething(); // Outputs "this.myName = Chris"
b.doSomething(); // Outputs "this.myName = Bob"
通过两个不同的对象调用的完全相同的函数对象具有不同的this指针。
exampleFunc是一个全局函数,我们称之为:
exampleFunc() // Outputs "this.myName = undefined"
那么undefined来自哪里呢?在全球范围内,"这个"设置为窗口(全局范围),它没有定义myName属性。这也意味着你可以这样做:
myName = "Global Name"; // note, no var - we want this global
exampleFunc(); // Outputs "this.myName = Global Name"
好的,那么原始问题又是怎么回事?基本上,你已经通过了函数this.click作为回调,但你还没有通过"这个"你希望它通过的指针。实际上,addEventListener没有办法传递this指针。因此,当调用该函数时,不指向您的对象。我不记得它头顶的东西 - 无论是窗口还是被点击的元素,请查看DOM文档进行验证。
为了让它用正确的上下文调用正确的函数(context =正确的" this"),传统的方法是使用闭包。捕获"这个"在一个变量中,然后传入一个匿名函数,该函数使用正确的指针调用您的实际回调。代码如下所示:
var preview = WinJS.Class.define(
function (el, options) {
// Capture your current this pointer in a global variable
// Using "that" as the name comes from JavaScript: The Good Parts book
var that = this;
el.winControl = this;
this.el = el;
this.textarea = d.getElementById('preview-input');
this.preview = d.getElementById('preview-text');
this.form = d.getElementById('perview-form');
// Note what gets passed instead of this.click:
this.preview.addEventListener('click',
function (e) {
// NOTE: Calling through "that": "this" isn't pointing to the right object anymore
// Calling through "that" resets "this" inside the call to click
that.click(e);
}, false);
},
{
click: function (e) {
this.form.style('display', 'block');
}
}
);
这是一个很常见的模式,ECMAScript 5有一个实用程序函数来为你构建这些包装器 - function.bind。这样做:
this.preview.addEventListener('click',
this.click.bind(this),
false);
构造this.click.bind(this)
将构造一个新函数,当被调用时,将设置" this"引用你传递的任何东西(在这种情况下"这个"),然后调用你调用它的函数。
是的,"这个"有很多不同的值。漂浮在周围。跟踪"这个"指向是掌握JavaScript编程的重要部分。
答案 1 :(得分:2)
我认为您可能希望将全局JavaScript变量定义为:
var myForm = document.getElementById('perview-form');
或jest定义var myForm;
并在function (el, options)
内初始化为:
myForm = d.getElementById('perview-form');
现在您可以在函数中使用此变量:
myForm.style('display', 'block');
编辑:我相信您可以将此变量定义为 WinJS.Class.define
的第一行,使其成为实例级变量,如下所示:
var preview = WinJS.Class.define(
var myForm;
function (el, options) {
....
....
myForm = d.getElementById('perview-form');
...
},
{
click: function (e) {
myForm.style('display', 'block');
}
});
答案 2 :(得分:1)
如果您不知道该寻找什么,这是一项非常难以研究的事情。我添加了一行并更改了另一行。这应该可以解决你的问题。
简而言之,每次输入新功能时,关键字this
都会重置,this
功能中的click
值不与外部范围相同。保留您想要的this
。 that
的名称似乎很常见。
根据OP提供的链接进行编辑
这段代码是UNTESTED。如果使用this
现在不起作用,那么我会尝试this2
对不起,我无法测试这个,但我没有任何地方的框架,所以我正在做
有教养的猜测。
var preview = WinJS.Class.define(
function (el, options) {
that = this; // No var should be needed since it is declared already
el.winControl = this;
this.el = el;
this.textarea = d.getElementById('preview-input');
this.preview = d.getElementById('preview-text');
this.form = d.getElementById('perview-form');
this.preview.addEventListener('click', this.click, false);
//WinJS.Utilities.query("button", this.form)
//this.preview.addEventListener('', this.save, false);
},
// This is the section for instance vars
{
click: function (e) {
that.form.style('display', 'block'); // AND THIS ONE
},
that: null // Added instance variable
},
// And these are static variables
{
that2: null
}
);