Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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 - Fatal编程技术网

此内部事件处理程序的JavaScript代码解释

此内部事件处理程序的JavaScript代码解释,javascript,Javascript,我有一些JavaScript代码可以正常工作。然而,我发现有点难以解释为什么它真的有效。我希望有人能告诉我。 我有一个对象必须响应某些事件,例如单击事件。对象的一部分如下所示: Maps.Marker = function (id, data, clickEvent) { this.id = id; this.data = data; this.clicked = clickEvent; }; if (marker.clicked) { // click handler

我有一些JavaScript代码可以正常工作。然而,我发现有点难以解释为什么它真的有效。我希望有人能告诉我。 我有一个对象必须响应某些事件,例如单击事件。对象的一部分如下所示:

Maps.Marker = function (id, data, clickEvent) {
    this.id = id;
    this.data = data;
    this.clicked = clickEvent;
};
if (marker.clicked) { // click handler defined
google.maps.event.addListener(m, "click", function () { 
        marker.clicked();
});
}
var objClicked = function () {
if (this.data != null) {...}
...
}
var obj = new Maps.Marker("1", { "some object data" }, objClicked);
  marker.clicked();
  var wrong = {};
  wrong.clicked = marker.clicked;
  wrong.clicked();
该对象在Google地图中呈现,因此当在地图中单击该对象时,我希望将事件气泡化为clickEvent。部分代码如下所示:

Maps.Marker = function (id, data, clickEvent) {
    this.id = id;
    this.data = data;
    this.clicked = clickEvent;
};
if (marker.clicked) { // click handler defined
google.maps.event.addListener(m, "click", function () { 
        marker.clicked();
});
}
var objClicked = function () {
if (this.data != null) {...}
...
}
var obj = new Maps.Marker("1", { "some object data" }, objClicked);
  marker.clicked();
  var wrong = {};
  wrong.clicked = marker.clicked;
  wrong.clicked();
请注意,为了简洁起见,我省略了很多代码,并且知道粘贴在这里的代码看起来是错误的。重要的是marker.clicked()函数是在GoogleMap事件侦听器中调用的

因此,当我的标记对象被实例化时,它看起来像这样:

Maps.Marker = function (id, data, clickEvent) {
    this.id = id;
    this.data = data;
    this.clicked = clickEvent;
};
if (marker.clicked) { // click handler defined
google.maps.event.addListener(m, "click", function () { 
        marker.clicked();
});
}
var objClicked = function () {
if (this.data != null) {...}
...
}
var obj = new Maps.Marker("1", { "some object data" }, objClicked);
  marker.clicked();
  var wrong = {};
  wrong.clicked = marker.clicked;
  wrong.clicked();
我不完全理解的是this.data在objClicked函数中的实际工作方式(我可以访问“一些对象数据”)。
有人能给我解释一下吗?

您可以这样调用函数:

Maps.Marker = function (id, data, clickEvent) {
    this.id = id;
    this.data = data;
    this.clicked = clickEvent;
};
if (marker.clicked) { // click handler defined
google.maps.event.addListener(m, "click", function () { 
        marker.clicked();
});
}
var objClicked = function () {
if (this.data != null) {...}
...
}
var obj = new Maps.Marker("1", { "some object data" }, objClicked);
  marker.clicked();
  var wrong = {};
  wrong.clicked = marker.clicked;
  wrong.clicked();
由于对函数的引用来自“marker”所指对象的“clicked”属性,因此该对象用于函数中的
this
值。JavaScript就是这样工作的

请注意,如果您做了这样奇怪的事情:

Maps.Marker = function (id, data, clickEvent) {
    this.id = id;
    this.data = data;
    this.clicked = clickEvent;
};
if (marker.clicked) { // click handler defined
google.maps.event.addListener(m, "click", function () { 
        marker.clicked();
});
}
var objClicked = function () {
if (this.data != null) {...}
...
}
var obj = new Maps.Marker("1", { "some object data" }, objClicked);
  marker.clicked();
  var wrong = {};
  wrong.clicked = marker.clicked;
  wrong.clicked();
那么你的代码就不能工作了,因为
这个
会引用那个“错误”的对象


因此,一般来说:如果一个对象有一个属性,属性值是对一个函数的引用,并且您通过引用调用该函数,那么函数中的
这个
将引用该对象。绑定发生在每个单独的函数调用上;函数和对象之间没有永久关系。(您可以使用类似于
.bind()
的东西获得永久关系的效果)

原因在于javascript中的
this
关键字的方式。当您将函数分配给对象内的属性,然后调用此函数时,
marker.clicked()
,函数中的
this
被设置为点左侧的任何值,在本例中,该值为
标记

更新


这里有一个更全面的解释:

感谢您的快速响应。您说“这就是JavaScript的工作原理”。您可以为这个功能添加一些特定的术语,比如作用域或…?或者甚至是一个解释此功能的链接?@user1632306它不是真正的“作用域”。请参阅第6步中有关设置此值的内容?(不幸的是,ECMA规范很难阅读和理解。)谢谢-回答得很好。我只是想确定它与我错过的闭包无关。这里有一个我更喜欢的链接:@ShadowScreer:真是太棒了!重复:@ShadowScreer:现在不是真的重复了,是吗?@chrisbuchholz我不确定。这一个更具体。所以可能不是。