Freewind
Freewind

Reputation: 198238

Reference another field inside a javascript object

I have an object in javascript:

admins: {
    articles: {
        path: '/admins/articles',
        template: '/views/admins/articles.html',
        link: function() {
            return path;  // !!! how to reference the 'path'?
        }
    }
}

I have a lot of objects like this, and each of them has a path field and a link function. I want to use the field path in link, but I can't just use path.

What should I do?

Upvotes: 16

Views: 13757

Answers (5)

Jeff Lowery
Jeff Lowery

Reputation: 2597

I'll just point out that you don't want to use ES6 fat arrow here, because there will be no this pointer in that case:

var someObj = {
    admins: {
        articles: {
            path: '/admins/articles',
            template: '/views/admins/articles.html',
            link: () => {
                return this.path; // 'this' is undefined
            }
        }
    }
};

someObj.admins.articles.link() === undefined

Upvotes: 5

Jason L.
Jason L.

Reputation: 2484

I won't talk about how this is not JSON (others covered it well).

You can do this to get path:

return admins.articles.path;

Here's a fiddle to show it working: http://jsfiddle.net/UwbLt/

Upvotes: 2

davidbuzatto
davidbuzatto

Reputation: 9424

I'm reading the answers and even understanding the point of some users (that JSON should be used just for data) and agreeing that this is correct, I just created a proof of concept example. Take a look.

// just a regular object
var obj = {
    a: "aaa",
    b: "bbb",
    c: function() {
        return this.a;
    }
};

console.log( obj.c() ); // prints "aaa"

// isn't it json just because it has a function? ExtJS will treat it like JSON, but jQuery not
var json = "{" +
    "\"a\": \"aaa\", " +
    "\"b\": \"bbb\", " +
    "\"c\": function() {" +
    "    return this.a;" +
    "}" +
"}";

// ok, the "json" above
console.log( json );

//var jsonObj = $.parseJSON( json ); // does not work
//var jsonObj = eval( json ); // does not work too
var jsonObj = Ext.decode( json ); // it works! shortcut for Ext.JSON.decode

console.log( jsonObj.c() );       // prints "aaa"

It is almost the same that nnnnnn posted, but I think I would post it too, just to complement the answers. jsFiddle: http://jsfiddle.net/davidbuzatto/rhKAM/

So I think, even contradicting the definition of JSON, that JSON maybe can have (or should have?) the same characteristics of a object created using the regular object initializer sintax, since its name is JavaScript Object Notation, not "Lightweight" Object Notation. I know, I know, a deserializer won't be able to deserialize a function depending on the target language, but why ExtJS supports this "behavior"? A good discussion can be found here: Is it valid to define functions in JSON results?

Just to clarify. I don't use (and I won't use too) functions inside my JSONs.

Upvotes: 1

nnnnnn
nnnnnn

Reputation: 150040

You can use this to reference the object. Standard object.method() "dot" syntax will set this to object within method:

var someObj = {
    admins: {
        articles: {
            path: '/admins/articles',
            template: '/views/admins/articles.html',
            link: function() {
                return this.path; // !!! how to reference the 'path'?
            }
        }
    }
};

var returnedPath = someObj.admins.articles.link();

Demo: http://jsfiddle.net/2Pt7n/

(There are other ways to call a function such that this will not be set to the appropriate object, but I hope they don't apply here - you don't really say how you're using the objects or calling the function, but if not in the way I showed then please update your question and I'll update my answer accordingly.)

Upvotes: 15

Ned Batchelder
Ned Batchelder

Reputation: 375604

What you are showing is not JSON. It is a Javascript object, which is different than JSON. JSON is a strictly defined data serialization format that is a subset of Javascript object literals.

Javascript provides no syntax for referencing peer properties in an object literal, as you want to do. Naming them is one idea, but it won't help, because the name won't exist while the literal is being defined, so the name is not available for you to use in the literal itself.

Also, note that the syntax you define makes the object lop-sided: you can access path as obj.admins.articles.path, but link is a function you would have to invoke: obj.admins.articles.link().

Upvotes: 2

Related Questions