我正在使用Google Maps API v3,我希望将我所做的API请求数量减少到最低限度。
对我来说,存储最后一个请求并测试下一个请求是否等于最后一个是有意义的,如果为真则忽略它:
var request = {
origin: "John O'Groats",
destination: "Land's End",
waypoints: [{
location: "Penrith",
stopover: true
}],
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
// Dont make a new request if same as last
if (request !== lastRequest) {
lastRequest = request;
directionsService.route(request, function(response, status) {
...
}
}
以上没有用。
所以我尝试了JSON.stringify
:
if (JSON.stringify(request) !== JSON.stringify(lastRequest)) {
仍然没有骰子。
然后我尝试了underscore.js isEqual
函数:
if (!_.isEqual(request, lastRequest)) {
再次无法工作。
以上所有都会返回错误的结果。我猜是因为wpts
是request
对象中的另一个对象。
如何在javascript中测试这两个对象的相等性?
Beetroot-Beetroot的回答让我走上正轨
因为只有一个对象然后尝试比较lastRequest 请求将始终产生真实 - 不能是其他任何东西。即使 对象的属性已更改,您仍将进行比较 改变了对象。
存储请求的字符串化版本以供以后测试解决了我的问题:
var request = {
origin: "John O'Groats",
destination: "Land's End",
waypoints: [{
location: "Penrith",
stopover: true
}],
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
requestStr = JSON.stringify(request);
// Dont make a new request if same as last
if (requestStr !== lastRequest) {
lastRequest = requestStr;
directionsService.route(request, function(response, status) {
...
}
}
答案 0 :(得分:1)
如果表达式的两边都是同一个对象实例,那么===
或==
运算符只会计算到true
,因此您将无法直接使用这些运算符来比较对象的基于其属性的平等。
但是,您可以实现自己的等式检查算法,如果您愿意,可以通过使用DirectionRequest
实例函数的equals
伪类来使用更简单的OO方法。
function DirectionRequest(data) {
this.origin = data.origin;
this.destination = data.destination;
this.waypoints = data.waypoints;
this.travelMode = data.travelMode;
}
DirectionRequest.prototype.equals = function (request) {
if (!(request instanceof this.constructor)) {
return false;
}
//equality checking algorithm e.g.
return this.origin === request.origin
&& this.destination === request.destination;
};
var req1 = new DirectionRequest({
origin: 'start', //just strings for the example
destination: 'end',
waypoints: 'wpts',
travelMode: 'driving'
}),
req2 = new DirectionRequest({
origin: 'start', //just strings for the example
destination: 'end',
waypoints: 'wpts',
travelMode: 'driving'
});
req1.equals(req2); //true
req1.equals({}); //false
编辑:
我已根据您的需求稍微修改了实现,请查看FIDDLE。对于waypoints
,您不能简单地检查this.waypoints === request.waypoints
是否与您一样,因为它只是检查数组实例是否是同一个对象。你最好只使用_.isEqual
,这将在两个对象之间进行深度比较。
DirectionRequest.prototype.equals = function(request) {
return _.isEqual(this, request);
};
答案 1 :(得分:0)
问题的根源在于lastRequest = request
。
Javascript对象是通过引用而不是值来分配的,因此lastRequest = request
只是创建第二个符号(lastRequest
),指向与原始符号(request
)相同的对象。
因为只有一个对象,所以将lastRequest
与request
进行比较的任何尝试都会产生true
- 不能是其他任何东西。即使对象的属性已更改,您仍将比较已更改的对象与自身。
然而......
jQuery包含了很棒的实用程序$.extend()
,它(以正确的方式使用)允许克隆javascript对象。
尝试:
lastRequest = $.extend({}, request);
现在将lastRequest
与request
进行比较将始终产生false
,因为request
和lastRequest
是不同的对象(无论其属性如何)。
但是......尝试你的stringify比较。它现在有很好的工作机会。