كيف أقوم بتمرير القيمة (وليس المرجع) لمتغير JS إلى وظيفة؟ [مكرر
-
24-09-2019 - |
سؤال
هذا السؤال لديه بالفعل إجابة هنا:
إليك نسخة مبسطة من شيء أحاول تشغيله:
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, 'click', function() {
change_selection(i);
});
}
لكنني أجد أن كل مستمع يستخدم قيمة النتائج. الطول (القيمة عندما تنتهي الحلقة). كيف يمكنني إضافة مستمعين بحيث يستخدم كل منهم قيمة I في الوقت الذي أضيفه فيه ، بدلاً من الإشارة إلى I؟
المحلول
في المتصفحات الحديثة ، يمكنك استخدام let
أو const
الكلمات الرئيسية لإنشاء متغير مكتوفي:
for (let i = 0; i < results.length; i++) {
let marker = results[i];
google.maps.event.addListener(marker, 'click', () => change_selection(i));
}
في المتصفحات القديمة ، تحتاج إلى إنشاء نطاق منفصل يحفظ المتغير في حالته الحالية عن طريق تمريره كمعلمة دالة:
for (var i = 0; i < results.length; i++) {
(function (i) {
marker = results[i];
google.maps.event.addListener(marker, 'click', function() {
change_selection(i);
});
})(i);
}
من خلال إنشاء وظيفة مجهولة ووصفها بالمتغير كوسيطة أول ، فأنت تمر بالقيمة إلى الوظيفة وإنشاء إغلاق.
نصائح أخرى
وكذلك الإغلاق ، يمكنك استخدام function.bind
:
google.maps.event.addListener(marker, 'click', change_selection.bind(null, i));
يمر قيمة i
في حجة إلى الوظيفة عند استدعاء. ((null
هو للربط this
, ، وهو ما لا تحتاجه في هذه الحالة.)
function.bind
تم تقديمه بواسطة إطار النموذج الأولي وتم توحيده في الطبعة الخامسة ECMASCRIPT. حتى تدعم المستعرضات جميعها أصليًا ، يمكنك إضافة خاصة بك function.bind
الدعم باستخدام الإغلاق:
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
الإغلاق:
for (var i = 0, l= results.length; i < l; i++) {
marker = results[i];
(function(index){
google.maps.event.addListener(marker, 'click', function() {
change_selection(index);
});
})(i);
}
تحرير ، 2013:يشار إليها الآن باسم iife
أنت تنتهي بإغلاق. هذا مقال عن الإغلاق وكيفية العمل معهم. تحقق من المثال 5 على الصفحة ؛ هذا هو السيناريو الذي تتعامل معه.
تحرير: بعد أربع سنوات ، هذا الرابط قد مات. جذر القضية أعلاه هو أن for
إغلاق أشكال الحلقة (على وجه التحديد على marker = results[i]
). مثل marker
يتم تمريرها addEventListener
, ، ترى التأثير الجانبي للإغلاق: يتم تحديث "البيئة" المشتركة مع كل تكرار للحلقة ، قبل أن يتم "حفظها" أخيرًا عبر الإغلاق بعد التكرار النهائي. MDN يشرح هذا جيدا جدا.
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, 'click', (function(i) {
return function(){
change_selection(i);
}
})(i));
}
أعتقد أنه يمكننا تحديد متغير مؤقت لتخزين قيمة i.
for (var i = 0; i < results.length; i++) {
var marker = results[i];
var j = i;
google.maps.event.addListener(marker, 'click', function() {
change_selection(j);
});
}
لم أختبرها رغم ذلك.