简体   繁体   English

Javascript对象文字表示法-创建mixins(多种)

[英]Javascript Object Literal Notation - Creating mixins (sort of)

For lack of a better title... Is it possible to do something like this in JSON? 由于缺少更好的标题...可以在JSON中执行类似的操作吗?

var obj = {
            a : 'a constant',
            b : a + ' and b constant'
}

Update: Doesn't work - this.a returns undefined I know this will work but it looks rather ugly and convoluted: 更新:不起作用-this.a返回undefined 我知道这会起作用,但是看起来很丑陋和令人费解:

 
 
 
 
  
  
  var obj = { a : 'a constant', b : (function(){ return this.a + ' and b constant'; })() }
 
 
  

And here's what I have currently: 这是我目前拥有的:

var obj = {
            a : 'a constant',
            b : 'a constant and b constant'
}

I know of the other ways that some have commented upon and I sincerely thank them for responding. 我知道有人对此发表了评论,并衷心感谢他们的回应。 However, they don't look simple or elegant. 但是,它们看起来并不简单或优雅。 The only issue I have with my current implementation is that if value of 'a' ever gets updated, search-n-replace has to done in many places (I say many because there are more properties that derive from 'a') instead of one. 我目前的实现方式唯一的问题是,如果'a'的值得到更新,则必须在许多地方执行search-n-replace(我说很多,因为有更多的属性源自'a'),而不是一。

In JSON, no. 在JSON中,不。 http://json.org/ http://json.org/

Did you mean in javascript? 您是指JavaScript吗?

JSON is a data format. JSON是一种数据格式。 It has no concept of functions, just like any other data format (HTML, XML, plain text). 与任何其他数据格式(HTML,XML,纯文本)一样,它没有功能的概念。

The only purpose this would seem to serve is data compression. 这似乎可以满足的唯一目的是数据压缩。 Why don't you just compress the data using one of the many standard implementations out there instead? 为什么不使用那里的许多标准实现之一来压缩数据呢?

If you expect your data to have massive redundancies of a sort that would not be efficiently compressed by a normal compression scheme, then you could do something like you're talking about here, eg 如果您希望数据具有某种大规模的冗余,而普通的压缩方案则无法有效地压缩它们,那么您可以做一些像在这里谈论的事情,例如

var obj = {
            a : 'a constant',
            b : '[fld=a] and b constant'
}

and your code at either end would have to implement and parse this. 而且您两端的代码都必须实现并解析此代码。 That is, it would search for [fld=x] in each member and substitute with the value of member x . 也就是说,它将在每个成员中搜索[fld=x]并替换为成员x的值。 But it's still just a custom data compression scheme. 但这仍然只是一个自定义数据压缩方案。 It has nothing to do with JSON. 它与JSON无关。

edit 编辑

Javascript Objects and JSON are entirely different (albeit related) things. Javascript ObjectsJSON是完全不同的(尽管相关)。 A Javascript object is any entity in Javascript. Javascript对象是Javascript中的任何实体。 JSON is a data format that is meant to represent the programmatic object in a text-based notation, specifically for the purpose of exchange with other programmatic entities across a wire (or when the internal format is otherwise not portable). JSON是一种数据格式,旨在以基于文本的符号表示程序对象,特别是为了通过导线与其他程序实体进行交换(或内部格式否则不可移植)。

If you are just asking if a Javascript object can contain a function that refers to another one of it's members, then sure, you already answered your own question! 如果您只是想问一个Javascript对象是否可以包含一个引用另一个成员的函数,那么可以肯定,您已经回答了自己的问题!

You don't need a self-executing function though, that just creates work, and it would also end up not reflecting any changes made to A in the future. 但是,您不需要自我执行功能,它只是创建工作,而且最终也不会反映出将来对A所做的任何更改。 Just do a regular function: 只需执行常规功能即可:

b : function() { return this.a + ' and b constant'; };

or more likely, just create a "method" and leave your fields alone: 或更可能的是,只需创建一个“方法”,然后不理会您的字段:

var obj = {
            a : 'a constant',
            b : 'b constant',
            ab: function() { return a+b }
}

Ok, here's a WAY to do it. 好的, 这是一种方法。 I don't know if this will work for you since it doesn't recurse, however give it a try. 我不知道这是否对您有用,因为它不会递归,但是请尝试一下。 This makes use of the reviver function to manipulate the data. 这利用了Reviver函数来操纵数据。

Note that the original string is a valid JSON string as you requested. 请注意,原始字符串是您所请求的有效JSON字符串。 As others have mentioned your examples are not valid JSON. 正如其他人提到的那样,您的示例不是有效的JSON。

Example

var json = '{"a":"a constant","b":"[get:a] and b constant","c":"test"}';
var jsonobj = JSON.parse(json, function(key, value) {
    //Ensure that value has the match function, ie. it's a string
    if (value.match) {
        //check for [get:xxx]
        var matches = value.match(/\[get:([^\]]*\])/g);
        //if something was found
        if (matches) {
            //Loop through each match.
            for (i=0; i<matches.length; i++) {
                //check if this object has that property
                if (this[matches[i].substring(5, matches[i].length-1)]) {
                    //If it does, replace the matched text with
                    //  the property's value.
                    // Note: It's split onto two lines for clarity on SO
                    value = value.replace(matches[i],
                             this[matches[i].substring(5, matches[i].length-1)]);
                }
            }
        }
    }
    return value; //Return the possibly modified value
});

Edit 编辑
Also, I tested this on Opera 11, IE8 and FF 3.6. 另外,我在Opera 11,IE8和FF 3.6上进行了测试。

var obj = {};
obj["a"] = "a constant";
obj["b"] = obj["a"] + " and b constant";

It's not pretty, and it's not JSON, but I think it's your only hope. 它不漂亮,也不是JSON,但我认为这是您唯一的希望。

Otherwise, mark up the JSON differently to fit your use case: 否则,请以不同的方式标记JSON以适合您的用例:

var obj = {
    a: "a constant",
    b: "and b constant",
    prependAB: true
}

...

if(obj.prependAB){
    alert(obj.a + obj.b);
}
else{
    alert(obj.b);
}

As far as I know, the short answer is no, though there are many ways to do this with more involved code. 据我所知,简短的答案是“不”,尽管有很多方法可以使用更多的相关代码。 The obvious one is to put a into a variable: 显而易见的是将a放入变量中:

a = 'a constant';
var obj = {
            a : a,
            b : a + ' and b constant'
}

The function-based approach would need to be called, not evaluated when you define the object: 在定义对象时,无需调用基于函数的方法,而无需对其进行评估:

var obj = {
        a : 'a constant',
        b : function(){ return this.a + ' and b constant'; }
}
obj.b();

The other approach, also probably stating the obvious, is a two-pass version: 另一种可能也表明明显的方法是两遍版本:

var obj = {
        a : 'a constant'
}
obj.b = obj.a + ' and b constant';

Found a potential solution: 找到了潜在的解决方案:

var obj = {
            a : 'a constant',
            b : obj.a + ' and b constant'
};

Thanks everyone for their tips! 感谢大家的提示! Upvoting all good suggestions. 赞成所有好的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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