Кэширование замыкания в JavaScript - PullRequest
2 голосов
/ 25 июня 2011

После прочтения ответа на вопрос: Внутренние функции JavaScript и производительность

Интересно, можно ли как-нибудь кэшировать внутреннюю функцию (doSomethingCool) в этом случае:

function newUser(user){
         function doSomethingCool(){
                 console.log(user);
         } 
}

Ответы [ 2 ]

4 голосов
/ 25 июня 2011

Вы не можете реально кэшировать замыкание . Если вы это сделаете, то он по-прежнему закрывает переменные функции, которую он впервые определил.

Например, вы можете подумать о том, чтобы сделать это, что на первый взгляд может показаться нормальным:

var newUser = (function() {
    var doSomethingCool;

    function newUser(user){
         doSomethingCool = doSomethingCool || function(){console.log(user);};
         doSomethingCool();
    }

    return newUser;
}());

При первом вызове newUser будет создана функция doSomethingCool. Это вывод:

> newUser('foo')
  foo

Когда мы вызываем функцию во второй раз, замыкание используется повторно. Это вывод:

> newUser('bar')
  foo

Почему? Поскольку замыкание только закрывает переменные функции , вызов был определен в.

Если вы действительно хотите «кэшировать» функцию, вы должны ее параметризовать:

var newUser = (function() {
    var doSomethingCool;

    function newUser(user){
         doSomethingCool = doSomethingCool || function(user){console.log(user);};
         doSomethingCool(user);
    }

    return newUser;
}());

Но я бы не назвал это закрытием. Технически это является закрытием, но вы не используете это свойство.

И на самом деле, гораздо проще написать это так:

var newUser = (function() {
    var doSomethingCool = function(user){...};

    function newUser(user){
         doSomethingCool(user);
    }

    return newUser;
}());
1 голос
/ 25 июня 2011

Смысл использования замыкания - сохранить контекст, в котором оно было создано.Если вы «кешируете» свое закрытие, ссылка на user всегда будет одинаковой, что противоречит цели.Вероятно, вам нужно что-то вроде:

function User(name) {
   this.name = name;
}

User.prototype.doSomethingCool = function() {
   console.log(this.name);
}

var userA = new User('a');
var userB = new User('b');

userA.doSomethingCool();
userB.doSomethingCool();

С этим кодом только одна функция doSomethingCool создается на прототипе User, но ее поведение изменяется в зависимости от того, как она вызывается.

Если вы просто хотите создать служебную функцию, которая используется только в newUser, но не использует свойства замыканий, вам, вероятно, будет лучше переместить функцию и принять пользователя в качестве аргумента.Тем не менее, я очень сомневаюсь, что оставив его там, это повлияет на вашу производительность любым заметным способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...