Javascript: отладка кода, созданного с помощью eval() и новой функции ()
Я пытаюсь поместить частную переменную в уже существующую функцию, пример:
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;"*/
Моя цель - запустить функцию get(), принадлежащую существующему AObject, с закрытой переменной... Я получаю ее, используя eval(или новую функцию), но, к сожалению, отладчик будет сломан!
Итак, есть способ достичь этого без использования eval или способ использовать eval и сохранить полезность отладчика?
6 ответов
Причина, по которой отладчик не указывает на строку в функции, заключается в том, что вызываемая вами функция вообще не связана (с точки зрения JavaScript) с AObject.get
функция. Eval не может знать, откуда взялась строка, определяющая функцию. Отладчик должен указывать на строку, где вы вызываете eval, потому что именно там определена функция, но она, очевидно, отключена линией.
Чтобы ответить на ваш вопрос, я не думаю, что есть способ избежать eval (или Function, которая, вероятно, будет предпочтительнее), если вы не можете переместить определение функции внутрь temp
поэтому он закрывается над "а" или добавить параметр "а" к get
функция.
@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
Вы понимаете сейчас?
Вы пытаетесь сделать что-то подобное???
var AObject={
get:function(s){
return s.toLowerCase()+this.a;
}
}
function temp(){
return {get:function(s){return AObject.get.call({a:"A"},s);}};
}
РЕДАКТИРОВАТЬ: после его комментария;
Знаете ли вы, что вы делаете, это довольно неправильно, это работает только потому, что eval меняет цепочку областей действия, в основном вы делаете это:
function temp(obj){
var a="A";
var o={};
o.get=function(s){
return s.toLowerCase()+a;
}
return o;
}
поскольку a находится в замыкании, это будет работать, но вы не вызываете истинную функцию obj get, вместо этого вы создаете другую, которая работает внутри temp;
Но, как я заявляю в комментарии, вы не должны писать функцию, которая содержит необъявленную переменную, вместо этого вы должны передать эту переменную в функцию, как это делает svinto.
Редактировать: удален неправильный код.
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();
Я думаю, используя eval
ваш единственный вариант, если вы хотите локальную переменную a
для использования внутри клонированной функции. Кроме того, я бы попробовал другой отладчик (Firebug на Firefox?)
@kentaromiura
Нет, ваш способ работает только потому, что вы помещаете переменную в область видимости окна (глобальная...)
Ваш ключ "this" является объектом "window", поэтому, когда вы делаете
this.a="A"
это как сделать
window["a"]="A"
Таким образом, стать глобальным вар
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
Это не обходной путь, должен быть частным, а не глобальным. Если я решу использовать глобальную переменную, я начинаю использовать глобальный вектор, где я могу хранить свою личную переменную. Спасибо.