最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Prevent getting error if variable is undefined? - Stack Overflow

programmeradmin2浏览0评论

I need to replace imagesrc with the value stored in this object. However when I run:

if(data['results'][res]['entities']['media']["0"]["media_url"]) {
    imagesrc = data['results'][res]['entities']['media']["0"]["media_url"];
}

I get the error:

Cannot read property '0' of undefined

How can I run my condition so that I don't get errors if something is undefined?

I need to replace imagesrc with the value stored in this object. However when I run:

if(data['results'][res]['entities']['media']["0"]["media_url"]) {
    imagesrc = data['results'][res]['entities']['media']["0"]["media_url"];
}

I get the error:

Cannot read property '0' of undefined

How can I run my condition so that I don't get errors if something is undefined?

Share Improve this question edited Jan 18, 2012 at 19:42 Colin Brock 21.6k9 gold badges49 silver badges62 bronze badges asked Jan 18, 2012 at 19:39 lisovaccarolisovaccaro 34k99 gold badges269 silver badges423 bronze badges 2
  • Check to see if it's undefined first: stackoverflow.com/questions/776950/… – Diodeus - James MacFarlane Commented Jan 18, 2012 at 19:42
  • Have you considered using try..catch? – Li0liQ Commented Jan 18, 2012 at 19:42
Add a comment  | 

5 Answers 5

Reset to default 4
if (data['results'][res]['entities']['media']["0"] == undefined
    || data['results'][res]['entities']['media']["0"] == null) {

    ...
}

You can place your code inside a try catch block and examine the error message.

try {
    imagesrc = data['results'][res]['entities']['media']["0"]["media_url"];
} catch (err) {
    if (err instanceof TypeError) imagesrc = undefined;
    else throw err;
}

You could write a function that walks the object tree and returns undefined as soon as it hits an undefined property:

function safeGetData(obj, names)
{
    for (var i = 0; i < names.length; ++i) {
        if (typeof obj === "undefined") {
            return undefined;
        }
        obj = obj[names[i]];
    }
    return obj;
}

You can use it like this:

var imagesrc = safeGetData(data,
    ["results", res, "entities", "media", "0", "media_url"]);

I’m a fan of using short circuit evaluation for these kinds of situations:

items && items[val] && doSomething(items[val])

Some people might be repulsed by this, but I think it’s a nice and readable way to express something that should only be evaluated if certain conditions are met.

In this case, we’re actually chaining two short circuit evaluations. First, we determine whether items has a defined value. If it undefined, then the rest of the expression is moot, so we won’t even bother to evaluate it. AND if it is defined, then let’s check for the existence of some property that we’re interested in. If it’s undefined, then bail out. AND if it’s true, we can go ahead and evaluate the rest of the expression.

I think it’s a lot easier to reason through at a glance than:

if (items) {
   if (items[val]) {
     doSomething(items[val])
   }
}

Ternary operators work similarly:

 items 
     ? items[val] 
         ? doSomething(items[val])
         :  alert(‘The property “‘ + val + ‘“ has not yet been defined.’)
     : alert(‘You have not yet defined any items!’)

It's an old topic, I know. It's just to add my 2 cents. I'm definitely not a javascript "guru", but here's one of my old attempts. It relies upon a couple of new ecmascript 6 features and it's going to approach the problem in a more "functional" way:

const prop = (...arr) => obj => arr.reduce((acc, v) => acc && acc.hasOwnProperty(v) ? acc[v] : undefined, obj)

And some tests in order to show how it should work:

describe('unit - prop', () => {
    const event = {
            record: {
                sns: {
                    subject: 'Hello',
                    message: '<div>Welcome!</div>'
                }
            }
        }

    it('property exists', done => {
        const value = prop('record', 'sns', 'subject')(event)
        expect(value)
            .to
            .be
            .equal('Hello')
        done()
    })

    it('property does not exist', done => {
        const value = prop('record', 'bad', 'subject')(event)
        expect(value)
            .to
            .be
            .undefined
        done()
    })
})

Does it make sense?

发布评论

评论列表(0)

  1. 暂无评论