blow
blow

Reputation:

Javascript: Debuging code created by eval() and new Function()

im trying for put a private var into an already existent function, example:

var AObject={
 get:function(s){
        return s.toLowerCase()+a;
    }    
}

function temp(){
    var a="A";
    var o={};
    eval("o.get="+AObject.get.toString());
    reurn o;
}

var bObject=temp();
BObject.get("B");    // "bA"
BObject.get();  /* error: s is undefined; but marked in line "return o;"
                    and not in "return s.toLowerCase()+a;"*/

My target is to run get() function, owned by an existent AObject, with private var ... Im obtain it using eval(or new Function), but unfortunly the debugger will be broke!

So, there is a way to achieve this without using eval, or a way to use eval and keep debugger useful?

Upvotes: 1

Views: 1295

Answers (6)

kentaromiura
kentaromiura

Reputation: 6499

Are you trying to do something like this???

var AObject={
 get:function(s){
        return s.toLowerCase()+this.a;
    }    
}

function temp(){

    return {get:function(s){return AObject.get.call({a:"A"},s);}};

}

EDIT: after his comment;

do you know, what you would do is pretty wrong, it works only because eval change the scope chain, basically you're doing this:

function temp(obj){
    var a="A";
    var o={};

    o.get=function(s){
            return s.toLowerCase()+a;
    }

    return o;
}

since a is in a closure, this will work, but you're not calling the true obj get function, instead you're creating another one that work inside temp;

But, as I state in the comment, you shouldn't write function that contains undeclared variable, instead you should pass this variable at the function, as svinto does.

Edit: deleted wrong code.

Upvotes: 0

blow
blow

Reputation:

@kentaromiura

No, your way works only becouse you put variable in window scope (global...)

Your "this" key is the "window" object, so when you do

this.a="A"

is like do

window["a"]="A"

In this way become a global var

function temp(obj){
    var a="A";

    return (function(){
        this.a =a;
        var o={};    
        o.get=function(s){return obj.get.call(this,s)};    
        return o;
    })();

}

var myObject=temp({
    get:function(s){
        return s.toLowerCase()+a;
    }
});

alert(myObject.get("B"));   //bA
alert(a); //A

This is not a workaround, must be private, not global. If i decide to use global var im starting to use a global vector where i can store my private var. Thank you.

Upvotes: 0

blow
blow

Reputation:

@svinto

function temp(obj){
    var a="A";
    var o={};
    eval("o.get="+obj.get.toString());
    reurn o;
}

var myObj=temp({
    get:function(s){
        return s.toLowerCase()+a;
    }
});

myObject.get("B");   //bA

Are you understand now?

Upvotes: 0

Svante Svenson
Svante Svenson

Reputation: 12478

function objectbuilder(a){
  return {
    get:function(s){
      return s.toLowerCase() + a;
    }
  };
}

function temp(){
  return objectBuilder("A");
}

var bObject=temp();
BObject.get("B");    // "bA"
BObject.get();

Upvotes: 0

Matthew Crumley
Matthew Crumley

Reputation: 102735

The reason the debugger doesn't point to the line in the function, is that the function you are calling is not related at all (as far as JavaScript is concerned) to the AObject.get function. Eval has no way of knowing where the string defining the function came from. The debugger should be pointing to the line where you call eval, because that's where the function is defined, but it's apparently off by a line.

To answer your question, I don't think there's a way to avoid eval (or Function, which would probably be preferable) unless you can move the function definition inside temp so it closes over "a" or add an "a" parameter to the get function.

Upvotes: 1

Ateş Göral
Ateş Göral

Reputation: 140112

I think using an eval is your only option, if you want the local variable a to be usable inside the cloned function. Also, I would try a different debugger (Firebug on Firefox?)

Upvotes: 0

Related Questions