ما الفرق بين "صفيف ()" و [] أثناء إعلان صفيف جافا سكريبت؟

StackOverflow https://stackoverflow.com/questions/931872

  •  06-09-2019
  •  | 
  •  

سؤال

ما هو الفرق الحقيقي بين إعلان صفيف مثل هذا:

var myArray = new Array();

و

var myArray = [];
هل كانت مفيدة؟

المحلول

هناك فرق، ولكن لا يوجد فرق في هذا المثال.

باستخدام طريقة Verbose أكثر: new Array() هل لديك خيار إضافي واحد في المعلمات: إذا قمت بتمرير رقم إلى المنشئ، فستحصل على مجموعة من هذا الطول:

x = new Array(5);
alert(x.length); // 5

لتوضيح الطرق المختلفة لإنشاء صفيف:

var a = [],            // these are the same
    b = new Array(),   // a and b are arrays with length 0

    c = ['foo', 'bar'],           // these are the same
    d = new Array('foo', 'bar'),  // c and d are arrays with 2 strings

    // these are different:
    e = [3]             // e.length == 1, e[0] == 3
    f = new Array(3),   // f.length == 3, f[0] == undefined

;

اختلاف آخر هو أنه عند استخدام new Array() أنت قادر على ضبط حجم الصفيف، مما يؤثر على حجم المكدس. هذا يمكن أن يكون مفيدا إذا كنت تحصل على تفيضات المكدس (أداء الصفيف. push vs array.unshift) وهو ما يحدث عندما يتجاوز حجم الصفيف حجم المكدس، وعليه إعادة إنشائه. لذلك يمكن أن يكون هناك بالفعل، اعتمادا على حالة الاستخدام، تكون زيادة في الأداء عند استخدامها new Array() لأنه يمكنك منع الفائض من الحدوث.

كما أشار في هذه الإجابة, new Array(5) لن تضيف بالفعل خمسة undefined العناصر إلى الصفيف. يضيف ببساطة مساحة لخمسة عناصر. كن على دراية باستخدام Array هذا الطريق يجعل من الصعب الاعتماد على array.length للحسابات.

نصائح أخرى

الفرق بين إنشاء صفيف مع الصفيف الضمني ومنشئ الصفيف هو دقيق ولكنه مهم.

عند إنشاء صفيف باستخدام

var a = [];

أنت تخبر مترجم شفوي لإنشاء صفيف تشغيل جديد. لا معالجة إضافية اللازمة على الإطلاق. منجز.

كما ترى:

var a = new Array();

أنت تخبر المترجم، أريد أن أسمي المنشئ "Array"وإنشاء كائن. ثم يبحث من خلال سياق التنفيذ الخاص بك للعثور على المنشئ للاتصال، ويسميها، وإنشاء صفيفك.

قد تفكر "حسنا، هذا لا يهم على الإطلاق. إنها هي نفسها!". لسوء الحظ، لا يمكنك ضمان ذلك.

اتخاذ المثال التالي:

function Array() {
    this.is = 'SPARTA';
}

var a = new Array();
var b = [];

alert(a.is);  // => 'SPARTA'
alert(b.is);  // => undefined
a.push('Woa'); // => TypeError: a.push is not a function
b.push('Woa'); // => 1 (OK)

في المثال أعلاه، سيتم تنبيه المكالمة الأولى "سبارتا" كما تريد. الثانية لن. سوف ينتهي بك المطاف رؤية غير محدد. سوف تلاحظ أيضا أن B يحتوي على جميع وظائف كائن الصفيف الأصلي مثل push, ، حيث الآخر لا.

بينما قد تتوقع أن يحدث هذا، فإنه يوضح حقيقة ذلك [] ليس هو نفسه new Array().

من الأفضل أن تستخدم فقط [] إذا كنت تعرف أنك تريد فقط صفيف. أنا أيضا لا أقترح الذهاب وإعادة تعريف الصفيف ...

هناك فرق كبير لا أحد ذكره.

قد تعتقد new Array(2) أي ما يعادل [undefined, undefined] من قبل لأن لدينا

new Array(2).length           // 2
new Array(2)[0] === undefined // true
new Array(2)[1] === undefined // true

لكنها ليست كذلك!

دعونا نحاول map():

[undefined, undefined].map(e => 1)  // [1, 1]
new Array(2).map(e => 1)            // "(2) [undefined × 2]" in Chrome

يرى؟ انها مختلفه! ولكن لماذا هذا؟

وفقا ل ES6 Spec 22.1.1.2، Array(len) فقط يخلق مجموعة جديدة مع length ضبط ل len ولا شيء أكثر. وبالتالي لا يوجد عنصر حقيقي داخل الصفيف الجديد.

بينما تعمل map(), ، وفقا للمواصفات 22.1.3.15 تحقق أولا HasProperty ثم استدعاء رد الاتصال، لكنه اتضح أن:

new Array(2).hasOwnProperty(0) // false
[undefined, undefined].hasOwnProperty(0) // true

لهذا السبب لا يمكنك أن تتوقع أن تعمل أي وظائف تكرار كالمعتاد للمجموعة التي تم إنشاؤها من new Array(len).

راجع للشغل، سفاري وفايرفوكس لديها تعبير أفضل بكثير لهذا:

// Safari
new Array(2)             // [](2)
new Array(2).map(e => 1) // [](2) 
[undefined, undefined]   // [undefined, undefined] (2) 

// Firefox
new Array(2)             // Array [ <2 empty slots> ]
new Array(2).map(e => 1) // Array [ <2 empty slots> ]
[undefined, undefined]   // Array [ undefined, undefined ]

لقد قدمت بالفعل مشكلة إلى Chrome لطلب منهم إصلاح هذا السجل المرتبط:https://bugs.chromium.org/p/chromium/issues/detail؟id=732021.

تحديث: لقد تم إصلاحه بالفعل. كروم الآن سجل

new Array(2)             // (2) [empty × 2]

الغريب، new Array(size) هو تقريبا 2x أسرع من [] في Chrome، وحول نفسه في FF و IE (تقاس بإنشاء وملء صفيف). يهم فقط إذا كنت تعرف الحجم التقريبي للمجموعة. إذا أضفت المزيد من العناصر من الطول الذي قدمته، فقد ضياع دفعة الأداء.

بدقة اكثر: Array( هي عملية وقت ثابت سريع تخصص أي ذاكرة، في حين [] هو عملية وقت خطي يحدد النوع والقيمة.

للمزيد من المعلومات، الصفحة التالية يصف لماذا لا تحتاج أبدا إلى استخدام new Array()

أنت لا تحتاج أبدا إلى استخدام new Object() في جافا سكريبت. استخدام الكائن الحرفي {}في حين أن. وبالمثل، لا تستخدم new Array()، استخدم مجموعة حرفية []في حين أن. لا يعمل المصفوفات في JavaScript لا شيء مثل المصفوفات الموجودة في جافا، واستخدام بناء جملة Java يشبه Java الخلط بينك.

لا تستخدم new Number, new String, ، أو new Boolean. وبعد تنتج هذه الأشكال مغلفة كائن غير ضرورية. مجرد استخدام حرفي بسيط بدلا من ذلك.

تحقق أيضا من التعليقات - new Array(length) لا يخدم النموذج أي غرض مفيد (على الأقل في تطبيقات اليوم عن جافا سكريبت).

من أجل فهم أفضل [] و new Array():

> []
  []
> new Array()
  []
> [] == []
  false
> [] === []
  false
> new Array() == new Array()
  false
> new Array() === new Array()
  false
> typeof ([])
  "object"
> typeof (new Array())
  "object"
> [] === new Array()
  false
> [] == new Array()
  false

النتيجة أعلاه هي من وحدة تحكم Google Chrome على نظام التشغيل Windows 7.

أول واحد هو مكالمة منشئ الكائن الافتراضي. يمكنك استخدام المعلمات الخاصة به إذا كنت تريد.

var array = new Array(5); //initialize with default length 5

الشخص الثاني يمنحك القدرة على إنشاء مجموعة فارغة:

var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.

يمكنني أن أشرح بطريقة أكثر تحديدا بدءا من هذا المثال الذي يعتمد على واحدة جيدة.

var test1 = [];
test1.push("value");
test1.push("value2");

var test2 = new Array();
test2.push("value");
test2.push("value2");

alert(test1);
alert(test2);
alert(test1 == test2);
alert(test1.value == test2.value);

أضفت فقط قيمة أخرى إلى المصفوفات، وقدمت أربعة تنبيهات: الأولى والثانية هي منحنا القيمة المخزنة في كل صفيف، للتأكد من القيم. سوف يعودون نفسه! حاول الآن الثالث، فإنه يعود خطأ، وهذا بسبب

JS يعامل Test1. ك متغير مع نوع البيانات من الصفيف, ، ويعامل Test2. كما كائن مع وظيفة صفيف, ، وهناك عدد قليل من الاختلافات الطفيفة هنا.

الفرق الأول هو عند استدعاء Test1، فهذا يستدعي متغير دون التفكير، فهو فقط إرجاع القيم المخزنة في هذا المتغير يتجاهل نوع بياناته! ولكن، عندما نسمي الاختبار 2 يستدعي مجموعة مصفوفة() وظيفة ثم يخزن لدينا "دفعت" القيم في لها "قيمة" العقار، ونفس الشيء يحدث عندما نتنبيه Test2، فإنه يعيد "قيمة" خاصية كائن الصفيف.

لذلك عندما نتحقق مما إذا كان Test1 يساوي Test2 بالطبع، فلن يعودوا أبدا صحيحا، واحدة هي وظيفة والآخر متغير (بنوع من الصفيف)، حتى لو كان لديهم نفس القيمة!

للتأكد من ذلك، جرب التنبيه الرابع، مع إضافة .Value إلى ذلك؛ سوف يعود صحيحا. في هذه الحالة، نقول JS "تجاهل نوع الحاوية، سواء كانت تعمل أو متغير، يرجى مقارنة القيم المخزنة في كل حاوية وأخبرنا بما رأيته!" هذا هو بالضبط ما يحدث.

آمل أن قلت الفكرة وراء ذلك بوضوح، وآسف لغتي الإنجليزية السيئة.

لا يوجد فرق عند عملية تهيئة صفيف دون أي طول. وبالتالي var a = [] & var b = new Array() هو نفسه.

ولكن إذا كنت تهيئة صفيف مع طول مثل var b = new Array(1);, ، سيقوم بتعيين طول كائن الصفيف إلى 1. لذلك ما يعادلها var b = []; b.length=1;.

سيكون هذا مشكلة كلما قمت بتصوير Array_Object.Push، فهذا يضيف عنصر بعد العنصر الأخير وزيادة الطول.

var b = new Array(1);
b.push("hello world");
console.log(b.length); // print 2

ضد

var v = [];
a.push("hello world");
console.log(b.length); // print 1

أول واحد هو استدعاء منشئ الكائن الافتراضي. يستخدم بشكل سريع للقيم الديناميكية.

var array = new Array(length); //initialize with default length

يتم استخدام الصفيف الثاني عند إنشاء قيم ثابتة

var array = [red, green, blue, yellow, white]; // this array will contain values.

لا يوجد فرق كبير، إنهم يفعلون نفس الشيء في الأساس ولكن يفعلونهم بطرق مختلفة، ولكن قرأوا، انظروا إلى هذا البيان في W3C:

var cars = ["Saab", "Volvo","BMW"];

و

var cars = new Array("Saab", "Volvo", "BMW");

المثالان أعلاه تفعل الشيء نفسه بالضبط. ليست هناك حاجة لاستخدام مجموعة جديدة ().
للبساطة، قابلية القراءة وسرعة التنفيذ، استخدم أول واحد (الطريقة الحرفية الصفيف).

ولكن في الوقت نفسه، خلق صفيف جديد باستخدام new Array بناء الجملة تعتبر ممارسة سيئة:

تجنب مجموعة جديدة ()

ليست هناك حاجة لاستخدام منشئ مجموعة JavaScript المدمج في مجموعة جديدة ().
استخدام [] بدلا من ذلك.
هذان البيانات المختلفة كلتا كلاهما يقومان بإنشاء صفيف فارغ جديد يدعى نقاطا:

var points = new Array();         // Bad
var points = [];                  // Good 

كل هذه العبارات المختلفة كلاهما يخلق مجموعة جديدة تحتوي على 6 أرقام:

var points = new Array(40, 100, 1, 5, 25, 10); // Bad    
var points = [40, 100, 1, 5, 25, 10];          // Good

ال الجديد الكلمة الرئيسية تعقد فقط التعليمات البرمجية. يمكن أن تنتج أيضا بعض النتائج غير المتوقعة:

var points = new Array(40, 100);  // Creates an array with two elements (40 and 100)

ماذا لو قمت بإزالة واحدة من العناصر؟

var points = new Array(40);       // Creates an array with 40 undefined elements !!!!!

لذلك لا تعتبر بشكل أساسي أفضل الممارسات، كما يوجد اختلاف طفيف واحد هناك، يمكنك تمرير طوله new Array(length) مثل هذا، والتي ليست أيضا طريقة موصى بها.

الفرق في استخدام

var arr = new Array(size);

أو

arr = [];
arr.length = size;

كما تمت مناقشته بما فيه الكفاية في هذا السؤال.

أود إضافة مشكلة السرعة - حاضر أسرع طريقة، على google chrome هو الثاني.

لكن الاهتمام، هذه الأشياء تميل إلى تغيير الكثير مع التحديثات. كما سيختلف وقت التشغيل بين المتصفحات المختلفة.

على سبيل المثال - يدير الخيار الثاني الذي ذكرته، عند 2 مليون [OPS / ثانيا chrome, ، ولكن إذا حاولت ذلك mozilla dev. كنت تحصل على معدل أعلى بشكل مدهش يبلغ 23 مليون.

على أي حال، أقترح عليك التحقق من ذلك، كل مرة واحدة، على المتصفحات المختلفة (والآلات)، باستخدام الموقع كما

كما أعرف أن الفرق يمكنك العثور على شريحة (أو funcitons الأخرى من الصفيف) مثل كود 1.كود 2 تظهر U. مجموعة مصفوفة كذالك هو الحالات:

كود 1:

[].slice; // find slice here
var arr = new Array();
arr.slice // find slice here
Array.prototype.slice // find slice here

كود 2:

[].__proto__ == Array.prototype; // true
var arr = new Array();
arr.__proto__ == Array.prototype; // true

خاتمة:

كما يمكنك أن ترى [] و new Array() قم بإنشاء مثيل جديد من الصفيف، وكلهم جميعا يحصلون على وظائف النموذج الأولي من Array.prototype

إنهم مجرد مثيل مختلف من الصفيف. لذلك يشرح هذا السبب[] != []

:)

لقد تكبدت في سلوك غريب باستخدام [].

لدينا نموذج "الطبقات" مع الحقول تهيأ إلى بعض القيمة. على سبيل المثال:

require([
  "dojo/_base/declare",
  "dijit/_WidgetBase",
], function(declare, parser, ready, _WidgetBase){

   declare("MyWidget", [_WidgetBase], {
     field1: [],
     field2: "",
     function1: function(),
     function2: function()
   });    
});

لقد وجدت أنه عندما يتم تهيئة الحقول مع [] ثم سيتم تقاسمها من قبل جميع الكائنات النموذجية. إجراء تغييرات على واحد يؤثر على جميع الآخرين.

هذا لا يحدث تهيئة لهم new Array(). وبعد نفسه لتحقيق الكائنات ({} مقابل جديد Object())

لست متأكدا مما إذا كانت مشكلة في الإطار الذي نستخدمه (دوجو)

لقد وجدت فرقا واحدا بين المنشورين الذي يفضلني بشدة.

دعنا نقول أن لدي:

function MyClass(){
  this.property1=[];
  this.property2=new Array();
};
var MyObject1=new MyClass();
var MyObject2=new MyClass();

في الحياة الحقيقية، إذا قمت بذلك:

MyObject1.property1.push('a');
MyObject1.property2.push('b');
MyObject2.property1.push('c');
MyObject2.property2.push('d');

ما ينتهي به هو هذا:

MyObject1.property1=['a','c']
MyObject1.property2=['b']
MyObject2.property1=['a','c']
MyObject2.property2=['d']

لا أعرف ما تقول مواصفات اللغة من المفترض أن يحدث ذلك، ولكن إذا كنت أريد أن يكون لدي كائلي من صفيف خصائص فريدة من نوعها في كائناتي، لا بد لي من استخدامها new Array().

إن استخدام منشئ الصفيف يجعل مجموعة جديدة من الطول المطلوب ويممل كل من المؤشرات مع undefined، يتم تعيين صفيف معين إلى متغير يقوم بإنشاء المؤشرات التي تعطيك معلومات عنها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top