Dado el código ES6 como
let a = new SomeClass(); let b = new AnotherClass(); let x = a.someMethod.bind(b, 1, 2, 3); let y = () => a.someMethod.call(b, 1, 2, 3);
¿Hay alguna diferencia significativa entre x
e y
? Sé que bind()
es una función mucho más antigua, pero ¿hay alguna necesidad de usarla sobre las funciones de flecha hoy en día?
Al menos para mí, la sintaxis de la función de flecha es mucho más fácil de leer que la sintaxis de bind()
, especialmente porque a menudo puedes evitar usar call()
en la práctica cuando this
tiene el significado normal del contexto léxico. Por ejemplo, ¿ bind()
tendrá un mejor rendimiento (CPU o RAM) en la práctica?
Independientemente del rendimiento, para algunos casos de uso, la función de flecha no puede representar la misma lógica. Por ejemplo, cuando usa Promesas, puede tener algo como esto ( fuente de este ejemplo ):
function CommentController(articles) { this.comments = []; articles.getList() .then(function (articles) { return Promise.all(articles.map(function (article) { return article.comments.getList(); })); }) .then(function (commentLists) { return commentLists.reduce(function (a, b) { return a.concat(b); }); }) .then(function (comments) { this.comments = comments; }.bind(this)); }
Tenga en cuenta la diferencia si se eliminó el último bind(this)
. No hay una manera simple de usar la notación de función de flecha para cambiar esto sin modificar mucho el código. Sin embargo, personalmente prefiero usar el cierre con un nombre de variable que no sea this
para un código como este.
Además, bind()
se puede usar para aplicaciones parciales que pueden ser más fáciles de leer para personas con experiencia en programación funcional .
Por otro lado, si a.someMethod
se modifica más tarde, la versión que usó bind()
no verá el cambio porque tomó la referencia a la función durante el enlace. La variante con la función lambda verá el valor actual de a.someMethod
cuando se llame a y()
.
Ejemplo adicional sobre la necesidad de .bind(this)
:
let f = { x: "bind data", test: function() { console.log("1. this=", this); setTimeout(function() { console.log("2. this=", this); }, 0); setTimeout(function() { console.log("3. this=", this); }.bind(this), 0); } } f.test();
let a = function(){}; let b = function(){}; am = 1 bm = 2 a.someMethod = function(x, y, z){ return this.m + x + y + z } let x = a.someMethod.bind(b, 1, 2, 3); let y = () => a.someMethod.call(b, 1, 2, 3) console.log( x(1,2,3) ) console.log( y(1,2,3) ) function goBind() { for (var i = 0; i < 1000000; i++) { x(1,2,3) } } function goArrow() { for (var i = 0; i < 1000000; i++) { y(1,2,3) } } function race() { var start = performance.now(); goBind(); console.log('bind: ' + (performance.now() - start)); start = performance.now(); goArrow() console.log('arrow: ' + (performance.now() - start)); start = performance.now(); goBind(); console.log('bind: ' + (performance.now() - start)); start = performance.now(); goArrow() console.log('arrow: ' + (performance.now() - start)); console.log('------'); }
<button onclick="race()">RACE!</button>
Basado en esto: ¿Son las funciones de flecha más rápidas (más eficientes, más livianas) que la declaración de función independiente ordinaria en v8?