简体   繁体   中英

confusion with hasOwnProperty

I wrote the below code, and some more, to quickly build a prototype for a 3 screen web application. Not planning to use it for production. The project is almost finished, but there is one issue that is perplexing me. I get an error - Cannot read property 'first_name' of undefined , even though there is a check first whether the object has the property reported as undefined. Realize the code is not an example of how such things should be handled, but why does it not work? To prevent context funkiness, I even clone the array - probably unnecessary. What causes the undefined error?

    $.ajax({
        url: '/api/v1/departures/' + routeID + '/',
        method: 'GET',
        headers: {
            'Authorization': 'Token '+ owner_token]
        },
        contentType:'application/json',
        success: function(departures) {
            console.log('departures: ' + JSON.stringify(departures));
            if ( departures && ( 0 < departures.length)) {
                var template = '';
                for ( var j = 0; j < departures.length; j++) {
                    if (departures[j].route == routeID) {
                        var seats = (departures[j].seats).slice(0);
                        for ( var i = 0; i < seats.length; i++) {
                            template  += '<div class="right-seat" data-id="' + seats[i].seat + '">' +
                                 '<div class="right-seat-place">SEAT ' + seats[i].seat + '</div>' +
                                 '<div class="right-seat-name">' +
                                 seats[i].hasOwnProperty('passenger') ? seats[i].passenger.first_name + ' ' + seats[i].passenger.last_name : '' +
                                 '</div>' +
                                 '<div class="right-seat-reserved"><i class="glyphicon glyphicon-check"></i>&nbsp;' +
                                 seats[i].hasOwnProperty('passenger') ? 'Reserved' : 'Available'  +
                                 '</div>' +
                                 '</div>';
                        }
                    }
                }
                $('div.right-top-controls').after(template);
            }
        },
        error: function() {
            alert('error!');
        }
    });

Please advise.

Thank you.

hasOwnProperty just checks if an object has a property by that name. It doesn't check what that value is. That value could be undefined .

 // Doesn't have the property and accessing it returns undefined var A = {}; console.log(A.hasOwnProperty('prop')); console.log(A.prop); // Has the property and the value is not undefined var B = { prop: 1 }; console.log(B.hasOwnProperty('prop')); console.log(B.prop); // Has the property AND it's value is undefined var C = { prop: undefined }; console.log(C.hasOwnProperty('prop')); console.log(C.prop);

This means that seats[i] may very well have a passenger property but it's value could still be undefined .

There's also the problem that you're using a ternary operation during string concatenation. Essentially, + has higher precedence than ?: which results in the concatenation occurring before the conditional is evaluated. To fix this, wrap your ternaries in parentheses.

template  += '<div class="right-seat" data-id="' + seats[i].seat + '">' +
               '<div class="right-seat-place">SEAT ' + seats[i].seat + '</div>' +
               '<div class="right-seat-name">' +
                 (seats[i].hasOwnProperty('passenger') ? seats[i].passenger.first_name + ' ' + seats[i].passenger.last_name : '') +
               '</div>' +
               '<div class="right-seat-reserved"><i class="glyphicon glyphicon-check"></i>&nbsp;' +
                 (seats[i].hasOwnProperty('passenger') ? 'Reserved' : 'Available')  +
               '</div>' +
             '</div>';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM