开发者

build an object without using of "new"

How can this object be rewritten so you don't need to declare it with "new"?

var Lang = new function(){
    this.get = function(str, trans){
        if(TRANSLATE[str]){
            var str = TRANSLATE[str][LANG];
            if(count_obj(trans) > 0){
                for(va开发者_如何学JAVAr key in trans){
                    str = str.replace('%'+key+'%', trans[key]);
                }
            }
        }

        return str;
    };
};

To something like this:

var Lang = {
get : function(){}
};


You wrote the solution to your own question in the question...this is a perfectly valid way to create an object in javascript:

var Lang = {
    get: function(str, trans){
        if(TRANSLATE[str]){
            var str = TRANSLATE[str][LANG];
            if(count_obj(trans) > 0){
                for(var key in trans){
                    str = str.replace('%'+key+'%', trans[key]);
                }
            }
        }

        return str;
    };
};

If you want private variables, the usual way to do that is to create a function with local variables that return the object with those variables encapsulated in a closure like so:

var Lang = (function() {
    var p1; // private variable
    var p2; // another private variable

    return {
       getP1: function () {
          return p1;
       },
       setP1: function(value) {
          p1 = value;
       }
    };
})();

Note that the function that creates the object you want is executed right away and returns the object with two private variables captured in the closure. Those variables will not be accessible from outside the object.


Patterns for Enforcing new

As mentioned already, constructors are still just functions but invoked with new. What happens if you forget new when you invoke a constructor? This is not going to cause syntax or runtime errors but might lead to logical errors and unexpected behavior. That’s because when you forget new, this inside the constructor will point to the global object. (In browsers this will point to window.)

When your constructor has something like this.member and you invoke the constructor without new, you’re actually creating a new property of the global object called member and accessible through window.member or simply member. This behavior is highly undesirable, because you know you should always strive for keeping the global namespace clean.

// constructor
function Waffle() {
   this.tastes = "yummy";
}
// a new object
var good_morning = new Waffle();
console.log(typeof good_morning); // "object"
console.log(good_morning.tastes); // "yummy"
// antipattern:
// forgotten `new`
var good_morning = Waffle();
console.log(typeof good_morning); // "undefined"
console.log(window.tastes); // "yummy"

Self-Invoking Constructor

To address the drawback of the previous pattern and have prototype properties available to the instance objects, consider the following approach. In the constructor you check whether this is an instance of your constructor, and if not, the constructor invokes itself again, this time properly with new:

function Waffle() {
   if (!(this instanceof Waffle)) {
      return new Waffle();
   }
   this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true;
// testing invocations
var first = new Waffle(),
second = Waffle();
console.log(first.tastes); // "yummy"
console.log(second.tastes); // "yummy"
console.log(first.wantAnother); // true
console.log(second.wantAnother); // true

Another general-purpose way to check the instance is to compare with arguments.callee instead of hard-coding the constructor name.

if (!(this instanceof arguments.callee)) {
   return new arguments.callee();
}

This pattern uses the fact that inside every function, an object called arguments is created containing all parameters passed to the function when it was invoked. And arguments has a property called callee, which points back to the function that was called. Be aware that arguments.callee is not allowed in ES5’s strict mode, so it’s best if you limit its future use and also remove any instances should you find them in existing code.

“JavaScript Patterns, by Stoyan Stefanov (O’Reilly). Copyright 2010 Yahoo!, Inc., 9780596806750.”


just leave the "new" out, rest is the same. :)

var Lang = function(){ 
...
}

Edit: example copy-paste from firebug, "dsa" is just an object, "dsaFunc" is a function, but you can do the same with them:

>>> var dsa = {};
undefined
>>> dsa.get = function(a){ return a+1;}
function()
>>> dsa.get(2)
3
>>> var dsaFunc = function(){};
undefined
>>> dsaFunc.get = function(a){ return a+1;}
function()
>>> dsaFunc.get(2)
3
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜