Проблема закрытия JavaScript снова! - PullRequest
0 голосов
/ 17 февраля 2011

Это то, с чем я сталкиваюсь

function AAA(){
    this.f1 = function (){
        /*expecting that f2 will be call as both of then are of same object.*/
        console.log(f2(5));//
    }

    this.f2 = function(x){
        return x;
    }
}

x = new AAA();
x.f1(); //ReferenceError: f2 is not defined

Это тоже не работает,

function AAA(){
    this.f1 = function (){
        /*expecting that f2 will be call as both of then are of same object.*/
        console.log(f3(5));//
    }

    /*naming the function f3 hope to get function reference, as function 
     on the right side has name now and in the closure of f1, right?*/
    this.f2 = function f3(x){
        return x;
    }

    function f4() {};
}

x = new AAA();
x.f1(); //ReferenceError: f3 is not defined

Что здесь происходит?кто находится в закрытии «f1», кроме «f4»?мы не можем вызвать ту же функцию объекта без 'this'?

Ответы [ 4 ]

3 голосов
/ 17 февраля 2011

Вы здесь не используете замыкания. Это будет работать нормально, если вы измените строку на

 console.log(this.f2(5));

Если вы хотите использовать замыкания, вы можете переписать класс следующим образом:

function AAA()
{
    var f1 = function()
    {
        console.log(f2(5));
    };

    // f2 is a private function.
    var f2 = function(x)
    {
        return x;
    };

    // Define the public interface.
    return { f1: f1 };
}
2 голосов
/ 17 февраля 2011

Вы путаете несколько вещей здесь; this и замыкания - это две совершенно разные проблемы.

Ваша проблема здесь в том, что вы пытаетесь обратиться к f2 напрямую, тем самым предполагая, что this является частью текущей области выполнения. Это не .
Если вы поставите f2 на this, вам придется ссылаться на него как this.f2. Чтобы иметь возможность ссылаться на f2 напрямую, вам нужно объявить (отдельную) переменную с этим именем, которую затем вы можете присвоить this, если хотите, как говорит qwertymk .

Лично я стараюсь избегать this столько, сколько могу, так как его значение полностью зависит от того, как вызывается функция (например, если AAA вызывается без указания оператора new, this будет обратитесь к глобальному объекту!). Это также спасает вас от головной боли, как та, что выше. Замыкания (как продемонстрировано Elian ) - намного лучший способ получить эту функциональность.
Интересно, что я обнаружил, что едва ли мне нужно , чтобы использовать this.

В примере Элиана f2 является закрытым по : после выполнения функции AAA никто не сможет получить доступ к f2, кроме функций, которые были определены внутри AAA (и все еще доступны). В этом случае функция f1 доступна из возвращенного объекта, так что она все еще существует. Следовательно, f1 все еще может использовать f2.
В этом суть замыканий: функция все еще может получить доступ ко всем переменным в своей области действия, даже если эти переменные были объявлены в завершающей функции.

1 голос
/ 17 февраля 2011

Это должно быть this.f2(), а не f2() само по себе. Вы бы использовали f2(), если бы это была закрытая переменная, что означает, что она была создана с ключевым словом var.

function AAA(){
    var f3 = function(x) { return x; };
    this.f1 = function (){
        /*expecting that f2 will be call as both of then are of same object.*/
        console.log(this.f2(5));//
        console.log(f3(10));
    }

    this.f2 = function(x){
        return x;
    }
}

DEMO

0 голосов
/ 17 февраля 2011

Другие уже говорили вам, в чем проблема, поэтому я не буду повторять это. Если вы хотите, чтобы ваш код работал, вам просто нужна ссылка на это:

function AAA(){
    var self = this;
    this.f1 = function (){
        console.log(self.f2(5)); //self.f2 exists, yay
    }

    this.f2 = function(x){
        return x;
    }
}

x = new AAA();
x.f1(); //5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...