JavaScript-разделители и замыкания - PullRequest
0 голосов
/ 24 октября 2018

Мне нужна помощь в понимании замыканий в JavaScript.Мне нужно сделать функцию (function1), которая вставляет указанный разделитель между элементами массива, или запятую, если разделитель не указан.Я пробовал это так, но это не работает.

function function1(separator)
{
    return function(elements)
    {
        for (var i = 0; i < elements.length; i++)
        return (`${elements}`+ separator);
    };
}


var ex1 = function1("/");
ex1("One"); 
ex1("Two"); 


var ex2 = function1("*");
ex2("One"); 
ex2("Two"); 


var ex3 = function1();
ex3("One");
ex3("Two");


console.log("ex1 is" + ex1() );
console.log("ex2 is " + ex2() );
console.log("ex3 is " + ex3() );

Вывод должен быть

ex1 is One/Two
ex2 is One*Two
ex3 is One,Two

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

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

Если ваша внешняя функция определяет массив, этот массив будет доступен для внутренней функции.Это закрытие.Затем возвращаемая функция возьмет один элемент и поместит его в массив компонентов.

function function1(separator){
    let components = []
    return function(element){
        // this function, even after returned, will have access to components
        // through a closure so you can push into components
        // and return something like components.join(separator)
     }
}

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

Edit - больше о замыканиях
Вот основная проблема: предположим, у вас есть функция, которая возвращает функцию, подобную этой:

function makelist(seperator){
   return function(element){
      let components = []
      components.push(element)
      return components
   }
 }
 
// now use it
// it returns a function
let myFun = makelist(",")

// but every time you run it, it makes a new components
console.log(myFun("a"))  // ["a"]
console.log(myFun("b"))  // ["b"]
// etc.

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

var GloablComponents = []

function makelist(seperator){
   return function(element){
      GloablComponents.push(element)
      return GloablComponents
   }
 }
 
// now use it
// it returns a function
let myFun = makelist(",")

// Now every time you use it, it pushes to the same array:
console.log(myFun("a"))  // ["a"]
console.log(myFun("b"))  // ["a", "b"]
// etc.

// But there's a problem:
// You want to make independent functions.
// If you make another, it pushes to myFun list as well:

let newFun = makelist(",")
console.log(newFun("C"))  // ["a", "b", "C"] // not what you want

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

Закрытия
Каждая функция создает свою собственную область, поэтому, если вы создаете функцию с переменной, а затем создаете другую функцию внутри нее, эта внутренняя функция увидит переменную, поскольку она имеет доступ к области действия внешней функции:

function makelist(seperator){
       let aLocalComponent = []         // <------ this out scope
       return function(element){        //          |
          aLocalComponent.push(element) // <-- THIS is referencing
          return aLocalComponent
       }
     }
     
// now use it
// it returns a function
let myFun = makelist(",")

// Now every time you use it, it pushes to the same array
// but it's not a global array, it's the array from
// makelist's scope. That's a closure
console.log(myFun("a"))  // ["a"]
console.log(myFun("b"))  // ["a", "b"]

// Now when make a new function, makelist makes another independent 
// scope. And the new function returned has access to it and its aLocalComponent

let mySecondFun = makelist(",")
console.log(mySecondFun("Z"))  // ["z"]

//At the sametime the old function still accesses the old localcomponentarray:
console.log(myFun("c"))     // only a, b, c

Вы можете использовать ту же идею, чтобы убедиться, что возвращаемые функции имеют одинаковый разделитель.

0 голосов
/ 24 октября 2018

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

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments:

function myConcat(separator) {
     var args = Array.prototype.slice.call(arguments, 1);
     return args.join(separator);
}

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

0 голосов
/ 24 октября 2018

function sepfnc(spchar){
    this.spchar = spchar;

    this.join = (a,b)=>{
        return a + this.spchar + b
     }

}


var t = new sepfnc("*");


var c =   t.join("a","b")

alert(c)

лучший способ - передать значения в виде массива, например

var inputArr = ["a","b"]

functionname("*" , inputArr )

, а затем поработать над их объединением

, если вы хотите использоватьчто-то вроде этого вы должны сохранить значение char в качестве объекта в вашей функции и использовать new ключевое слово

как

function sepfnc(spchar){
    this.spchar = spchar;

    this.join = (a,b)=>{
        return a + this.spchar + b
     }

}


var t = new sepfnc("*");


var c =   t.join("a","b")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...