السلام عليكم و رحمه الله تعالى و بركاته
هذا الموضوع يعتمد فى بعض اجزائه على ماتم شرحه فى سلسله جافاسكربت الموجهه بالكائنات .
كما ذكرت من قبل فى موضوع نسخ الجافاسكربت ، زادت الجافاسكربت 1.6 بوظائف جديده للمصفوفه و بمواصفات E4X ، هذه الزيادات متاحه فى FireFox 1.5+ و Opera و Safari و AIR و Google Chrome ، اما ال E4X موجود فى فايرفوكس فقط .
Array.indexOf
اول وظيفه هى من وظائف المصفوفه هى indexOf ، تشبه نفس طريقه عمل String.indexOf حيث تقوم بجلب index العنصر الذى تم تمريره لها كعباره او ترجع -1 ان لم تجده فى المصفوفه ، كما يوضح المثال البسيط التالى :
var arr = ["a","b","c","d"];
alert(arr.indexOf("c")); // 2
alert(arr.indexOf("x")); // -1
تقبل أيضا عباره تانيه اختياريه و هى ال index الذى يبدأ عنده البحث – القيمه الافتراضيه له 0- كما يوضح الكود البسيط التالى :
var arr = ["a","b","e","a","z"];
alert(arr.indexOf("a",1)); // 3
الوظيفه Array.indexOf غير موجوده فى JavaScript 1.5 ، لكن يمكن اضافتها عن طريق التعديل على Array.prototype حتى ترثها جميع المصفوفات كما يوضح الكود البسيط التالى الذى يعتمد على ماتم شرحه فى سلسله جافاسكربت الموجهه بالكائنات :
if(!Array.prototype.indexOf){
Array.prototype.indexOf = function(elem /*, from*/){
var length = this.length;
var from = Number(arguments[0]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
for(; from<length; from++){
if(from in this &&
this[from]==elem){
return from;
}
}
return -1;
}
}
بالطبع يمكنك الان استخدام Array.indexOf فى جافاسكربت 1.5 بعد كتابه الكود السابق .
ِArray.lastIndexOf
ثانى وظيفه هى lastIndexOf ، تشبه نفس طريقه عمل String.lastIndexOf تقوم بجلب index العنصر الذى يمرر لها لكنها تبدأ من اخر المصفوفه او ترجع -1 ان لم تجد هذا العنصر ، و ايضا تقبل عباره تانيه ال index الذى يبدأ عنده البحث -القيمه الافتراضيه له array.length- كما يوضح الكود البسيط التالى :
var arr = [3,1,0,5,3];
alert(arr.lastIndexOf(3)); //4
alert(arr.lastIndexOf(3,5)); //4
alert(arr.lastIndexOf(3,-2)); //0
alert(arr.lastIndexOf(9)); //-1
الوظيفه Array.lastIndexOf غير موجوده فى JavaScript 1.5 ، و لكن يمكن اضافتها بالتعديل على Array.prototype كما يوضح الكود البسيط التالى :
if(!Array.prototype.lastIndexOf){
Array.prototype.lastIndexOf = function(elem /*, startIndex*/){
var length = this.length;
var from = Number(arguments[1]);
if(isNaN(from)){
from = length-1;
}
else {
from = (from<0)
? Math.ceil(from)
: Math.floor(from);
if(from<0){
from += length;
}
else if(from>=length){
from = length-1;
}
}
for(; from>-1; from++){
if (from in this && this[from]== elem){
return from;
}
}
return -1;
}
}
عن طريق الكود السابق يمكننا استخدامها بأمان فى المتصفحات التى تدعم JavaScript 1.5 فقط .
Array.every
الوظيفه every تختبر هل عناصر المصفوفه ستجتاز الوظيفه التى تمرر لها ام لا ، حيث ان الوظيفه التى تمرر ل every يتم تمرير لها 3 عبارات : الاولى عنصر المصفوفه ، الثانيه ترتيبه فى المصوفه ، الثالث مرجع للمصفوفه نفسها ، الوظيفه every ترجع القيم true اذا ارجعت كل عناصر المصفوفه true ، اوترجع القيمه false إذا ارجعت احدى عناصر المصفوفه false و يمكن استخدامها كما يلى :
var arr=[1,2,3,4,5,6];
// وظيفه لاختبار هل العنصر الذى يمرر لها فردى ام لا
function odd(x){
return x%2;
}
arr.every(odd); //false
// اختبار قيمه عناصر المصفوفه كلها اقل من عشره
arr.every(function(elem,index,arr){
return elem<10;
}); //true
الوظيفه every غير موجوده فى جافاسكربت 1.5 ، و لكن يمكننا زيادتها على ال Array.prototype حتى ترثها كل المصفوفات و يمكننا استخدامها بامان كما يوضح الكود التالى :
if(! Array.prototype.every){
Array.prototype.every = function(fn /*, thisObject*/){
var length = this.length;
if(typeof fn != "function"){
throw new TypeError();
}
var thisObject = arguments[1];
for(var i=0; i<length; i+=1){
if(i in this &&
!fn.call(thisObject,this[i],i,this)){
return false;
}
}
}
}
و بإضافه الكود السابق يمكننا استخدام array.every بأمان .
Array.filter
الوظيفه filter تقوم بفلتره عناصر المصفوفه ، حيث ترجع العناصر التى ترجع true مع الوظيفه التى تمرر لها ، تقبل الوظيفه every عبارتين : الاولى الوظيفه التى يتم فلتره عناصر المصفوفه بها ، العباره الثانيه الكائن الذى يحل محل this عند استدعاء هذه الوظيفه ، عليك ملاحظه ان filter لا تغير المصفوفه لذلك عليك استقبال النتيجه فى متغير جديد ، كما توضح الامثله البسيطه التاليه :
var arr = [1,2,3,4,5,6,7,8];
var evenNumbers = arr.filter(function(elem){
return elem%2==0;
}); //[2,4,6,8]
[5,7,8,9,10,11,12,13].filter(function(){
return elem>10;
}); //[11,12,13]
الوظيفه filter غير موجوده فى جافاسكربت 1.5 ، و لكن يمكن اضافتها عن طريق الاضافه على Array.prototype كما يوضح الكود البسيط التالى :
if(!Array.prototype.filter){
Array.prototype.filter = function(fn /*, thisObject*/){
var length = this.length;
if(typeof fn != "function"){
throw new TypeError();
}
var result = [];
for(var i=0; i<length; i+=1){
var val = this[i];
if(fn.call(thisObject, val, i, this)){
result.push(val);
}
}
return result;
}
}
بعد إضافه الكود السابق يمكنك استخدمها فى المتصفحات التى تعمل فى بيئه جافاسكربت 1.5 بدون مشاكل .
Array.forEach
الوظيفه forEach تقوم بتنفيذ الوظيفه التى تمرر لها على جميع عناصرها ، لاتتغير المصفوفه ولا ترجع الوظيفه شيئا، يمرر للوظيفه forEach عبارتين : الأولى الوظيفه التى سيتم تنفيذها على جميع عناصر المصفوفه ، الثانيه الكائن الذى سيحل محل this عند استدعاء الوظيفه ، كما توضح المثال البسيط التالي :
var arr = [1,2,3,4]
function multiply(x){
alert(x*x);
}
arr.forEach(mulitply); // 1,4,9,16
جافاسكربت 1.5 لا تحتوى على forEach و لككننا يمكننا اضفتها على ال Array.prototype بكل سهوله كما يوضح الكود البسيط التالى :
if(!Array.prototype.forEach){
Array.prototype.forEach = function(fn /*, thisObject*/){
var length = this.length;
if(typeof fn != "function"){
throw new TypeError();
}
var thisObject = arguments[i];
for(var i=0; i<length; i+=1){
if(i in this){
fn.call(thisObject, this[i], i, this);
}
}
}
}
Array.map
الوظيفه map تعمل بنفس طريقه Array.forEach غير انها ترجع الناتج فى مصفوفه جديده ، بعكس Array.forEach التى لا ترجع ناتج ، الوظيفه map تقبل عبارتين الاولى الوظيفه التى ستنفذ على جميع عناصرها ، و العباره التانيه الكائن الذى سيحل محل this عند استدعاء الوظيفه ، كما توضح الامثله البسيطه التاليه :
var arr=[1,2,3,4];
var result = arr.map(function(x){
return x*10;
}); //[10,20,30,40];
جافاسكربت 1.5 لا تحتوى على map و لككننا يمكننا اضفتها على ال Array.prototype بكل سهوله كما يوضح الكود البسيط التالى :
if(!Array.prototype.map){
Array.prototype.map = function(fn /*, thisObject*/){
var length = this.length;
if(typeof fn != "function"){
throw new TypeError();
}
var thisObject = arguments[1];
var result = [];
for(var i=0; i<length; i+=1){
if(i in this){
result[i] = fn.call(thisObject, this[i], i, this);
}
}
return result;
}
}
Array.some
و اخيرا الوظيفه some تختبر هل احدى عناصر المصفوفه ستعطى true اذا مررت للوظيفه التى تمرر ل some ، حيث تعطى true اذا اعطت اخدى العناصر القيمه true او تعطى false اذا اعطت كل العناصر القيمه false ، مع ملاحظه ان الوظيفه some لا تغير المصفوفه لذلك لابد من استقبال الناتج فى متغير جديد ، حيث تقبل some عبارتين الاولى هى الوظيفه التى ستم اتنفيذها على كل عناصرها ، و العباره التانيه هى الكائن الذى سيحل محل this عند استدعاء الوظيفه ، كما يوضح المثال البسيط التالى :
var arr = ["Amhed Ali","Eman Nader","Mostafa Farghaly"];
function anaMawgood(x){
return x.toLowerCase()=="Mostafa Farghaly";
}
alert(arr.some(anaMawgood)); // true
جافاسكربت 1.5 لا تحتوى على some و لككننا يمكننا اضفتها على ال Array.prototype بكل سهوله كما يوضح الكود البسيط التالى :
if(! Array.prototype.some){
Array.prototype.some = function(fn /*, thisObject*/){
var length = this.length;
if(typeof fn != "function"){
throw new TypeError();
}
var thisObject = arguments[1];
for(var i=0; i<length; i+=1){
if(i in this && fn.call(thisObject, this[i], i, this)){
return true;
}
}
return false;
}
}
بإضافه الكود السابق يمكننا استخدام some فى جافاسكربت 1.5 .
Aray generics
اضافه يضا جافاسكربت 1.6 امكانيه استخدام وظائف ال Array على انواع اخرى غير المصفوفه بدون الخوض فى سلسله ال prototype كما يوضح المثال التالى :
function isLetter(character){
return (character >= "a" && character <= "z");
}
var str="Mostafa Farghaly";
if(Array.prototype.every.call(str,isLetter)){
alert("str contains only letters!");
}
يمكنك استبدال الكود الذى يخوض فى سلسله ال protoype كالاتى :
if(Array.every(str,isLetter)){
alert("str contains only letters!");
}
ملحوظه الكود السابق يعمل على فايرفوكس فقط .
للمزيد : New in JavaScript 1.6 و Mozilla new Array methods .