2

Google Maps API v3 を使用していますが、作成する API リクエストの数を最小限に抑えたいと考えています。

最後に行われたリクエストを保存し、次のリクエストが最後と等しいかどうかをテストし、true の場合は無視することは理にかなっています。

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でこれら2つのオブジェクトの同等性をテストするにはどうすればよいですか?

解決

Beetroot-Beetrootの答えは私を正しい軌道に乗せました

オブジェクトは 1 つしかないため、lastRequest と request を比較しようとすると、常に true が返されます。それ以外にはなり得ません。オブジェクトのプロパティが変更された場合でも、変更されたオブジェクトをそれ自体と比較することになります。

後でテストするためにリクエストの文字列化されたバージョンを保存すると、問題が解決しました。

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) {

            ...

    }
}
4

2 に答える 2

1

===or演算子は、式の両側が同じオブジェクト インスタンスである場合==にのみ評価されるため、これらの演算子を直接使用して、プロパティに基づいてオブジェクトの等価性を比較することはできません。true

ただし、独自の等値チェック アルゴリズムを実装することもできます。必要に応じて、インスタンス関数を持つDirectionRequest疑似クラスを使用することで、もう少し OO アプローチを使用することもできます。equals

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に which を使用する方がよいでしょう。

DirectionRequest.prototype.equals = function(request) {
    return _.isEqual(this, request);
};
于 2013-09-28T20:50:49.643 に答える
0

問題の根源は にありますlastRequest = request

Javascript オブジェクトは値ではなく参照によって割り当てられるため、元のシンボル ( ) と同じオブジェクトを指すlastRequest = request2 番目のシンボル ( ) を作成するだけです。lastRequestrequest

オブジェクトは 1 つしかないため、比較しようとすると常に結果lastRequestrequest得られます。それ以外のオブジェクトはtrueできません。オブジェクトのプロパティが変更された場合でも、変更されたオブジェクトをそれ自体と比較することになります。

でも ...

jQuery には優れたユーティリティが含まれており$.extend()、(正しい方法で使用すると) JavaScript オブジェクトのクローンを作成できます。

試す :

lastRequest = $.extend({}, request);

とは異なるオブジェクトであるため(プロパティに関係なく)、 との比較lastRequestrequest常に生成されます。falserequestlastRequest

しかし... stringifyの比較を試してください。これで、うまく機能する可能性が高くなります。

于 2013-09-29T02:57:43.613 に答える