Почему bind, похоже, представляет аргументы в виде массивов?

#javascript

#javascript

Вопрос:

У меня сложилось впечатление, что я мог бы передавать аргументы функции с помощью using bind , а затем вызывать эти аргументы, как если бы они были переданы нормально. Зачем мне это нужно:

 $(document).ready(function() {
  var func = function(button) {
    button[0].on('click', function() {
      alert('Hello World.');
    })
  }
  func.bind(null, [$('.button')])();
});
  

Когда кажется, что я должен быть в состоянии просто сделать это:

 $(document).ready(function() {
  var func = function(button) {
    button.on('click', function() {
      alert('Hello World.');
    })
  }
  func.bind(null, [$('.button')])();
});
  

Например, обработка button аргумента как массива:

 $(document).ready(function() {
  var func = function(button) {
    button[0].on('click', function() {
      alert('Hello World.');
    })
  }
  func.bind(null, [$('.button')])();
});  
 html, body, div {
  padding:0;
  margin:0;
  display:flex;
  justify-content:center;
}

.button {
  background-color:gray;
  margin:50px;
  padding:50px;
  width:50%;
}  
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="button">Button</div>  

Комментарии:

1. Он обрабатывает его как массив, потому что вы привязываете массив.

Ответ №1:

bind() используется для привязки текущей области вызова к функции, так что даже если вы вызываете ее откуда-то еще, она будет знать о локальных переменных в этой связанной области.

То, что вы ищете, это apply() .

 var func = function(button) {
  button.on('click', function() {
    console.log('hello world');
  });
}

func.apply(this, [$('.button')]);  
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="button">Click Me</button>  

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

 func.call(this, $('.button'));
  

Комментарии:

1. .apply() лучше, но даже это не имеет особого смысла здесь, когда .call() может использоваться вместо этого. Не забудьте удалить завершающий ()

2. Ах да, я пропустил () завершение. Я тоже изначально предлагал call() , но казалось, что OP хотел иметь возможность передавать массив аргументов, так apply() что это самый правильный подход.

3. Я вижу, да, если у OP уже есть массив, то .apply() это решение.

4. Я добавил замечание о call() для полноты ответа.

Ответ №2:

Вы используете .bind неправильно. Вы не должны давать ему массив аргументов, вы должны просто указывать сами аргументы:

 function print(x, y, z) {
  console.log(x, y, z);      
}

print12 = print.bind(null, 1, 2);

print12(3); // 1, 2, 3  

Кроме того, как упоминал Совиут, если вы вызываете .bind(...)() , вы, вероятно, хотите .apply() или .call() вместо этого.

Комментарии:

1. О, что, если у меня есть динамическое количество аргументов, которые я хочу передать функции? Редактировать: я вижу, приведенный выше ответ показывает, что мне нужно использовать apply

2. @curiosity5678 Используйте что-то вроде .apply(null, [arg1, arg2, arg3, ...])

3. @curiosity5678 Если вы хотите вызвать bind с динамическим количеством аргументов, которые вы используете Function.bind.apply(myFunction, [thisValue, arg1, arg2 /* ... */])

4. Или ES6 var bound = myFunction.bind(thisArg, ...myArrayOfArgs)