具有可变作用域的JavaScript循环问题
因此,我有了这个jQuery具有可变作用域的JavaScript循环问题,javascript,jquery,variables,scope,each,Javascript,Jquery,Variables,Scope,Each,因此,我有了这个jQuery。每个循环,并且在很大程度上它是按预期工作的;有一个问题,但首先是循环: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head>
。每个循环,并且在很大程度上它是按预期工作的;有一个问题,但首先是循环:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
<script type="text/javascript">
function Pushpin(){}
Pushpin.prototype.XZX = {
site: null,
getHtmlDescription: function () {
var html = '<b id="infoboxTitle" style="position:absolute; top:10px; left:10px; width:220px;">' + this.site.Name + '</b>';
html += '<a id="infoboxDescription" style="position:absolute; top:30px; left:10px; width:220px; height:120px;">{0}</a>';
var description = 'Headcount: ' + this.site.Headcount + '<br />';
description += 'Leases: ' + this.site.LeaseCount + '<br />';
html = html.replace('{0}', description);
return html;
}
};
var data = [
{"Address":{"City":"Atlanta","Country":"USA","County":"","Latitude":33.9882404987503,"Longitude":-84.1629638209203,"Region":"Southeast","State":"GA","StreetAddress":"Atlanta 177","ZipCode":"30096"},"Headcount":0,"ImageBytes":null,"ImageRefPath":"","LeaseCount":1,"Leases":null,"Name":"Atlanta","NextExpire":"\/Date(1495083600000-0500)\/","Number":"1052","PrimaryUse":"Garage","PropertyID":"OMNI","RecID":32839,"RecordID":1004,"RentableSquareFootage":22000,"SiteRecordID":"DEMO_29626","SiteTotalDollars":0,"Status":null,"Type":"LSE"},
{"Address":{"City":"Bellevue","Country":"USA","County":"","Latitude":47.6043250620083,"Longitude":-122.14236047437,"Region":"Northwest","State":"WA","StreetAddress":"Seattle 51","ZipCode":"98007"},"Headcount":0,"ImageBytes":null,"ImageRefPath":"","LeaseCount":1,"Leases":null,"Name":"Bellevue","NextExpire":"\/Date(1260424800000-0600)\/","Number":"1078","PrimaryUse":"Tower","PropertyID":"OMNI","RecID":32865,"RecordID":1027,"RentableSquareFootage":7652,"SiteRecordID":"DEMO_275651","SiteTotalDollars":0,"Status":null,"Type":"LSE"}
];
var mylist = [];
$.each(data, function (i, item) {
try {
var pin = new Pushpin();
pin.XZX.site = item;
mylist.push(pin);
} catch (e) { alert (e); }
});
$(document).ready(function() {
$('#btnAlert').click(function () {
$('#content').html(mylist[$('#index').val()].XZX.getHtmlDescription());
} );
});
</script>
</head>
<body >
<div style="margin-left:auto; margin-right:auto; width:300px;">
<div style="position:relative; width:250px;">
<select id="index">
<option>0</option>
<option>1</option>
</select>
<input type="submit" id="btnAlert"/>
</div>
<div id="content" style="position:relative;width:250px;"></div>
</div>
</body>
</html>
函数Pushpin(){}
图钉.prototype.XZX={
站点:空,
getHtmlDescription:函数(){
var html=''+this.site.Name+'';
html+='
在循环结束时,mylist[x].site
对于任何x
都指向我的数据项的同一实例,我如何绕过这个问题?问题是每个pin.XYZ
都是相同的对象,即Pushpin.prototype.XYZ
简单的“修复”是使用:
var pin = new Pushpin(...)
pin.XYZ = {
site: item
// the following will get tedious fast, consider one of the "property copy"
// implementations floating about -- including jQuery.extend
getHtmlDescription: Pushpin.prototype.XYZ.getHtmlDescription
}
这将为每个新图钉对象的XYZ
属性分配一个新对象。当然,这也可以有不同的设计:)
至少,将XYZ
从Pushpin.prototype对象上移开——这将允许它被很好地视为一个对象(传递this
的方式实际上使得悬挂在原型对象上的函数几乎不可能访问原型应用的对象的实例数据);结束代码可能类似于:
// We .. "wrap" the real Pushpin constructor
// somewhere global after Bing Mapi JS loaded
Pushpin = (function (bingPushpin) {
return function Pushpin (...) {
var pin = new bingPushpin(...)
pin.XYZ = new XYZ()
// trick of "returning" from ctor
return pin
}
})(PushPin)
// ...
var pin = new Pushpin(...)
pin.XYZ.site = item
快乐编码
更新前答复:
这实际上不是一个范围问题——没有意外创建的闭包,每个表达式都经过严格的计算
我怀疑还有另一个问题,比如意外的输入(数据包含一堆相同的项目)或者有缺陷的假设(比如对象被神奇地克隆)或者一些无关的东西
快乐编码
分析:
var mylist = [];
$.each(data, function (i, item) {
// creates new object
var pin = new Pushpin(x, y);
// property of new object assigned
// remember that no "duplication" is occurring
pin.site = item;
// new object pushed to array
mylist.push(pin);
});
因此,没有任何pin
是相同的,但是item
有可能在每个循环中对同一个对象求值。(唯一的例外是,如果图钉构造函数使用return
返回一个现有对象,这将是一个有趣的好办法。)是否需要在.each之外声明var pin?
然后将其设置为新的。每个
var pin;
var mylist = [];
$.each(data, function (i, item) {
try {
pin = new Pushpin(x, y);
pin.site = item;
mylist.push(pin);
} catch (e) { alert (e); }
});
考虑到你在一个函数中,我会说是的,当然它们都指向同一个对象,因为你只是通过引用传递。环顾四周后,我偶然发现了这一点——但似乎没有克隆Javascript对象的直接选项
也许你最好的方法是编写一个函数,克隆一个输入对象并将其作为新实例返回?在阅读了MoarCodePlz的答案后,我认为这可能有助于解决“通过引用”的问题。但尚未验证它
var mylist = [];
$.each(data, function (i, item) {
// Creates the new object as a part of yourlist
mylist.push(new Pushpin(x, y));
// property of new object assigned item
mylist[x].site = item;
});
这不会解决任何问题。赋值永远不会创建新对象(为了简单起见,基本值可以从讨论中排除)。好的。我认为值得一试。:)图钉来自Bing地图(不确定是否使用返回
)。我已经验证了项
在循环中每次都是不同的。@Nate不用担心图钉ctor——它会以非常奇妙的方式破坏一切。你有显示行为的最小测试用例吗?(这是一个发布它的好地方,也是在原始帖子中发布的好地方)。对于测试用例,使用var pin={}就足够了
并删除Bing映射依赖项。不,我会尝试获取一个。如果我的,会有什么不同吗。每个循环都在$调用的回调中。getJSON
调用?Nate不是固有的,但更大的上下文可能包含更多线索。好吧,我有一个测试用例来演示我看到的行为:迂腐:JavaScript中的对象是非按引用传递(引用是一种底层实现技术/细节,在JavaScript语言中从未公开)。相反,JavaScript对象作为自身传递(不是副本、克隆或复制)。这种调用行为称为。