Я не знаю, возможно ли это вообще, но, скажем, у нас есть следующий код:

var name = 'John';

function log() {
    console.log('Hello ' + name );
}

function greetTravis() {
    var name = 'Travis';

    log(); // This function is defined outside greetTravis's scope. 
}


greetTravis();
log();

Результат:

Hello John // Is there a workaround to get "Hello Travis"?
Hello John

Жестко запрограммированное решение (я не хочу повторяться)

var name = 'John';

function log() {
    console.log('Hello ' + name );
}

function greetTravis() {
    var name = 'Travis';

    log(); // Now, it is defined inside greetTravis's scope. 

    function log() {
        console.log('Hello ' + name );
    }

}


greetTravis();
log();

Что мне нужно:

Я хотел бы получить доступ к переменной name (той, что находится внутри greetTravis ()) из функции log, не передавая переменную, возможно, используя функцию, которая изменяет область действия log (), что-то вроде: call / bind.

Примечание: функции вызова и привязки позволяют изменять контекст (это) не область .

4
CryptoBird 21 Авг 2018 в 20:22

4 ответа

Лучший ответ

Краткий ответ: Да, вы можете: -ДО, но это не рекомендуется.

Длинный ответ. В Javascript лексическая область определяется тем, где в коде написано объявление функции, и чтобы изменить лексическую область во время выполнения, вы должны использовать функция eval (даже если она немного снизит производительность ) следующим образом:

var name = 'John';

function log() {
    console.log('Hello ' + name );
}
function greetTravis() {
    var name = 'Travis';

    eval( log.toString() ); // <==== The added code.

    log();

}

greetTravis();
log();

В этом случае использование eval () абсолютно безопасно ( eval () не является злом ).

1
CryptoBird 23 Авг 2018 в 13:39

Чтобы получить желаемый результат, вам нужно просто выполнить рефакторинг log, чтобы оно заняло имя, которое вы хотите зарегистрировать.

К вашему сведению - у объекта window есть свойство с именем name. Поэтому лучше не использовать name в качестве глобального в вашем коде.

var userName = 'John';

function log(val) {
    console.log('Hello ' + val );
}

function greetTravis() {
    var userName = 'Travis';

    log(userName); // This function is defined outside greetTravis's scope. 
}


greetTravis();
log(userName);
2
Scott Marcus 21 Авг 2018 в 17:32

В этом случае функция log () имеет доступ только к имени глобальной переменной. Для того, чтобы он отображал локальную переменную, вам нужно получить «имя» по параметру

0
Henrique Viana 21 Авг 2018 в 17:28

Думаю, не все так просто.

Если вы не использовали var name = 'Travis'; внутри greetTravis, вы бы перезаписали глобальное значение, но затем, когда log(); вызывается во второй раз, он также будет регистрировать Hello Travis.

Я думаю, что ты хочешь что-то вроде

function createPersonObj(name) {
    return { // this must be on the same line
        name: name
    }
}

var name = 'John';
var personJohn = createPersonObj(name);

function log() {
    console.log('Hello ' + this.name );
}

function greetTravis() {
    var name = 'Travis';
    var personTravis = createPersonObj(name);

    log.call(personTravis);
}

greetTravis();
log.call(personJohn);

Не делая Джона объектом, вы можете вместо этого проверить this.name внутри log(), и, если существует, использовать его, в противном случае использовать name

function log() {
    var nameToLog = (this.name !== undefined)
        ? this.name
        : name;
    console.log('Hello ' + nameToLog );
}

Источник: https: // www. codementor.io/niladrisekhardutta/how-to-call-apply-and-bind-in-javascript-8i1jca6jp

Проверьте пример кода ниже для вызова ()

//Demo with javascript .call()

var obj = {name:"Niladri"};

var greeting = function(a,b,c){
    return "welcome "+this.name+" to "+a+" "+b+" in "+c;
};

console.log(greeting.call(obj,"Newtown","KOLKATA","WB"));
// returns output as welcome Niladri to Newtown KOLKATA in WB

Первый параметр в методе call () устанавливает значение «this», то есть объект, для которого вызывается функция. В данном случае это объект obj выше.

Остальные параметры являются аргументами фактической функции.

2
Amatore Eld 21 Авг 2018 в 17:49
51953812