JavaScript новичок здесь. У меня есть следующий код:

function testObject(elem) {
    this.test = "hi";
    this.val = elem;
    console.log(this.test+this.val);
    echo();

    function echo () {
        console.log(this.test+this.val);
    }
}

var obj = new testObject("hello");

Когда он запустится, я ожидаю, что "hihello" будет дважды выведен на консоль. Вместо этого он выводит, как ожидалось, в первый раз, но возвращает NaN во второй раз.

Я уверен, что я что-то здесь упускаю. Я думал, что внутренняя функция может получить доступ к переменным, проводимым снаружи. Может ли кто-нибудь, пожалуйста, вести меня? Я более функциональный разработчик пользовательского интерфейса и не имею большого опыта работы с ОО-кодом.

Благодарность!

3
Newbie Coder 4 Авг 2010 в 00:08

3 ответа

Лучший ответ

Проблема в том, что внутри echo значение this указывает на глобальный объект, а this.test и this.val (которые ссылаются на window.test и {{X5} }) undefined.

Вы можете установить значение this для echo, вызвав его следующим образом:

echo.call(this);

Это происходит потому, что вы вызывали функцию с помощью echo();, тогда значение this неявно устанавливается для глобального объекта.

Ознакомьтесь с этим вопросом, чтобы узнать, как работает значение this.

Редактировать . Чтобы иметь возможность вызывать просто echo();, вы должны сохранить значение this из контекста внешней функции, для этого есть много способов, например:

//...
var instance = this; // save the outer `this` value
function echo (){
  console.log(instance.test+instance.val); // use it
}
echo();
//...

Или же

//...
var echo = (function (instance) {
  return function () {
    console.log(instance.test+instance.val);
  };
})(this); // pass the outer `this` value
echo();
//...
4
Community 23 Май 2017 в 10:28

Вы также можете сделать это:

function testObject(elem) {
    this.test = "hi";
    this.val = elem;
    console.log(this.test+this.val);

    this.echo = function () {
        console.log(this.test+this.val);
    }
    this.echo();
}

var obj = new testObject("hello");

Всякий раз, когда вы вызываете this.echo() или obj.echo(), this будет привязан к объекту, вызывающему функцию.

3
Felix Kling 3 Авг 2010 в 20:14

Лично я считаю элегантным объявление таких методов класса:

function testObject(elem) {
    this.test = "hi";
    this.val = elem;
    this.echo();
}

testObject.prototype = {
    echo: function () {
        console.log(this.test + this.val);
    }
}

var obj = new testObject("hello");
1
jmc 3 Авг 2010 в 23:21