জেএসলিন্ট ত্রুটিটি 'আই-এর বিবৃতিতে জড়িত হওয়া উচিত' এর জন্য বডিটির মানে কী?


242

আমি আমার একটি জাভাস্ক্রিপ্ট ফাইলটিতে জেএসলিন্ট ব্যবহার করেছি । এটি ত্রুটি নিক্ষেপ করেছে:

for( ind in evtListeners ) {

লাইন 41 অক্ষর 9 এ সমস্যা: প্রোটোটাইপ থেকে অযাচিত বৈশিষ্ট্যগুলি ফিল্টার করার জন্য একটি ইন-এর বডি যদি একটি বিবৃতিতে আবৃত করা উচিত।

এটার মানে কি?


5
ডিফল্টরূপে 'ইন' উত্তরাধিকারসূত্রে প্রাপ্ত বৈশিষ্ট্যগুলিও পুনরুক্ত করে। সাধারণত, শরীর if (evtListeners.hasOwnProperty(ind))কেবলমাত্র (অ-উত্তরাধিকারসূত্রে) বৈশিষ্ট্যগুলির মধ্যে প্রসেসিং সীমাবদ্ধ করতে আবৃত থাকে । তবুও, কিছু ক্ষেত্রে আপনি উত্তরাধিকার সূত্রে প্রাপ্ত সমস্ত সম্পত্তি সহ সত্যই পুনরাবৃত্তি করতে চান। সেক্ষেত্রে, জেএসলিন্ট আপনাকে কোন বৈশিষ্ট্যটি চান তা স্থির করতে যদি একটি বিবৃতিতে লুপের দেহটি মোড়তে বাধ্য করে। এটি কাজ করবে এবং জেस्্লিন্টকে খুশি করবে: if (evtListeners[ind] !== undefined)
xorcus

1
বেশিরভাগ উত্তর পুরানো। একটি আপডেট সমাধান stackoverflow.com/a/10167931/3138375
ইলি বিডি

উত্তর:


430

প্রথমত, অ্যারের উপরে গণনা করতে কখনইfor in লুপ ব্যবহার করবেন না । কখনও। পুরানো ভাল ব্যবহার করুন for(var i = 0; i<arr.length; i++)

এর পিছনে কারণগুলি নিম্নরূপ: জাভাস্ক্রিপ্টের প্রতিটি বস্তুর একটি বিশেষ ক্ষেত্র বলা হয় prototype। আপনি যে ক্ষেত্রে সমস্ত কিছু যুক্ত করেন তা সেই ধরণের প্রতিটি বস্তুর অ্যাক্সেসযোগ্য হতে চলেছে। মনে করুন আপনি সমস্ত অ্যারেতে একটি শীতল নতুন ফাংশন রাখতে চান যা filter_0শূন্যগুলি ফিল্টার করবে।

Array.prototype.filter_0 = function() {
    var res = [];
    for (var i = 0; i < this.length; i++) {
        if (this[i] != 0) {
            res.push(this[i]);
        }
    }
    return res;
};

console.log([0, 5, 0, 3, 0, 1, 0].filter_0());
//prints [5,3,1]

এটি অবজেক্টগুলি প্রসারিত এবং নতুন পদ্ধতি যুক্ত করার একটি স্ট্যান্ডার্ড উপায়। প্রচুর গ্রন্থাগার এটি করে। যাইহোক, for inএখন কীভাবে কাজ করে তা দেখুন :

var listeners = ["a", "b", "c"];
for (o in listeners) {
    console.log(o);
}
//prints:
//  0
//  1
//  2
//  filter_0

তুমি কি দেখছ? এটি হঠাৎ করেই মনে করে যে ফিল্টারটি আর একটি সূচি সূচক। অবশ্যই, এটি আসলে একটি সংখ্যাসূচক সূচক নয়, তবে for inঅবজেক্ট ফিল্ডগুলির মাধ্যমে অঙ্ক করা হবে, কেবল সংখ্যা সূচকগুলি নয়। সুতরাং আমরা এখন প্রতিটি সংখ্যার সূচক এবং মাধ্যমে গণনা করছি filter_0। তবে filter_0কোনও নির্দিষ্ট অ্যারে অবজেক্টের ক্ষেত্র নয়, প্রতিটি অ্যারে অবজেক্টের এখন এই সম্পত্তি রয়েছে।

ভাগ্যক্রমে, সমস্ত অবজেক্টের একটি hasOwnPropertyপদ্ধতি রয়েছে যা যাচাই করে যে এই ক্ষেত্রটি সত্যিকার অর্থে অবজেক্টের অন্তর্ভুক্ত কিনা বা এটি কেবল প্রোটোটাইপ শৃঙ্খল থেকে উত্তরাধিকার সূত্রে প্রাপ্ত এবং এটি সেই ধরণের সমস্ত বস্তুর অন্তর্ভুক্ত।

for (o in listeners) {
    if (listeners.hasOwnProperty(o)) {
       console.log(o);
    }
}
 //prints:
 //  0
 //  1
 //  2

দ্রষ্টব্য, যদিও এই কোডটি অ্যারেগুলির প্রত্যাশার মতো কাজ করে, আপনার কখনই, কখনই , ব্যবহার for inএবং for each inঅ্যারে ব্যবহার করা উচিত নয় । মনে রাখবেন যে for inঅ্যারে সূচি বা মানগুলি নয়, কোনও অবজেক্টের ক্ষেত্রগুলি গণনা করে।

var listeners = ["a", "b", "c"];
listeners.happy = "Happy debugging";

for (o in listeners) {
    if (listeners.hasOwnProperty(o)) {
       console.log(o);
    }
}

 //prints:
 //  0
 //  1
 //  2
 //  happy

43
for inঅ্যারেগুলিতে পুনরাবৃত্তি করার জন্য আপনার ব্যবহার করা উচিত নয় কারণ ভাষাটি কোনও অ্যারেতে অঙ্কিত হবে সেই ক্রমটি গ্যারান্টি করে না for in। এটি সংখ্যার ক্রমে নাও থাকতে পারে। এছাড়াও, আপনি যদি (i = 0; i <অ্যারে.লেন্থ; i++) স্টাইল কন্সট্রাক্টের জন্য use ব্যবহার করেন তবে আপনি নিশ্চিত হতে পারেন যে আপনি কেবলমাত্র সংখ্যা অনুসারে ক্রম অনুসারে পুনরাবৃত্তি করছেন এবং কোনও বর্ণানুক্রমিক বৈশিষ্ট্য নেই।
ব্রেটন

ধন্যবাদ! আমি এটি একটি রেফারেন্স হিসাবে সংরক্ষণ করব।
nyuszika7h

আমি নিজেকে এই উত্তরটির দিকে আবার তাকিয়ে দেখলাম কারণ আমি নিশ্চিত যে জেএসলিন্টের এই বিটটি ভেঙে গেছে। আমার কাছে কোড ছিল যা মোটামুটি ছিল: (শ্রোতাদের মধ্যে) - যদি (শ্রোতা .হাসনপ্রোপার্টি (আই)) so কনসোল.লগ (ও); ।} সমস্যাটি হ'ল আমার একটি ত্রুটি ছিল, আমি ভেরিয়েবলের নামগুলি আমি ওগুলিতে স্যুইচ করেছি এবং একটি রেফারেন্স মিস করেছি। জেএসলিন্ট সঠিক আইটেমের সঠিক সম্পত্তিটির জন্য আপনার মালিকানা পরীক্ষা করেছেন তা নিশ্চিত করার জন্য যথেষ্ট স্মার্ট।
অনুমান করুন

12
ইন জন্য, তবে, কোনও সামগ্রীর সম্পত্তি নিয়ে পুনরাবৃত্তি করা ঠিক fine ওপি কখনই বলেনি যে জন্য কোনও অ্যারে প্রয়োগ করা হয়েছিল। HasOwnProperty হ'ল সর্বোত্তম অনুশীলন, তবে এমন কিছু ক্ষেত্রে রয়েছে যেখানে আপনি এটি চান না - উদাহরণস্বরূপ যদি কোনও বস্তু অন্যটিকে প্রসারিত করে এবং আপনি উভয় বস্তু এবং 'পিতামাতা' এর সম্পত্তি দুটির তালিকা করতে চান।
gotofritz

3
আমি মনে করি যে লোকগুলিকে for-inলুপগুলি থেকে দূরে সরিয়ে দেওয়ার পরিবর্তে (যা দুর্দান্তভাবেই হয়) তারা কীভাবে কাজ করে তা আমাদের শিক্ষিত করা উচিত (এই উত্তরে সঠিকভাবে সম্পন্ন করা হয়েছে) এবং তাদের পরিচয় করিয়ে দেওয়া Object.defineProperty()যাতে তারা কিছু না ভেঙে নিরাপদে তাদের প্রোটোটাইপগুলি প্রসারিত করতে পারে। ঘটনাচক্রে, নেটিভ অবজেক্টের প্রোটোটাইপগুলি ছাড়াই করা উচিত নয়Object.defineProperty
রবার্ট রোসম্যান

87

Jslint এর লেখক ডগলাস ক্রকফোর্ড বহুবার এই সমস্যাটি সম্পর্কে লিখেছেন (এবং কথা বলেছেন)। তাঁর ওয়েবসাইটের এই পৃষ্ঠায় একটি বিভাগ রয়েছে যা এটির অন্তর্ভুক্ত:

বিবৃতি জন্য

বিবৃতি শ্রেণীর জন্য ক এর নিম্নলিখিত ফর্মটি থাকতে হবে:

for (initialization; condition; update) {
    statements
}

for (variable in object) {
    if (filter) {
        statements
    } 
}

প্রথম ফর্মটি অ্যারে এবং পূর্বনির্ধারিত সংখ্যার পুনরাবৃত্তির লুপগুলির সাথে ব্যবহার করা উচিত।

দ্বিতীয় ফর্মটি অবজেক্টগুলির সাথে ব্যবহার করা উচিত। সচেতন হন যে অবজেক্টের প্রোটোটাইপের সাথে যুক্ত সদস্যগণকে গণনায় অন্তর্ভুক্ত করা হবে। অবজেক্টের সত্যিকারের সদস্যদের আলাদা করতে hasOwNProperty পদ্ধতি ব্যবহার করে ডিফেন্সিভ প্রোগ্রাম করা বুদ্ধিমানের কাজ:

for (variable in object) {
    if (object.hasOwnProperty(variable)) {
        statements
    } 
}

ক্রকফোর্ডের ওয়াইউআই থিয়েটারে একটি ভিডিও সিরিজ রয়েছে যেখানে তিনি এই বিষয়ে কথা বলেছেন। জাভাস্ক্রিপ্ট সম্পর্কে ক্রকফোর্ডের সিরিজ ভিডিও / আলোচনার বিষয়গুলি অবশ্যই আপনাকে জাভাস্ক্রিপ্ট সম্পর্কে কিছুটা গুরুতর কিনা তা দেখতে হবে।


21

খারাপ: (jsHint একটি ত্রুটি ফেলবে)

for (var name in item) {
    console.log(item[name]);
}

ভাল:

for (var name in item) {
  if (item.hasOwnProperty(name)) {
    console.log(item[name]);
  }
}

8

ভাবার উত্তর চিহ্নে আছে। আপনি যদি jQuery ব্যবহার করেন তবে $.each()ফাংশনটি এটির যত্ন নেয় তাই এটি ব্যবহার করা নিরাপদ।

$.each(evtListeners, function(index, elem) {
    // your code
});

5
পারফরম্যান্সটি যদি এখানে বিবেচনা করা হয় তবে আপনি কাঁচা লুপটি সরিয়ে নিতে পারলে আমি $.each(বা আন্ডারস্কোর.জেএস _.each) ব্যবহার করার পরামর্শ দেব না for। jsperf এর কয়েকটি চক্ষু খোলার তুলনা পরীক্ষা রয়েছে যা চলমান।
নিকব

3
এটি ( jsperf.com/each-vs-each-vs- for-in/3 ) আরও বাস্তববাদী কারণ এটি বেসিক প্রোটো ফিল্টার নিযুক্ত করে
dvdrtrgn

7

@ সমস্ত - জাভাস্ক্রিপ্টের সমস্ত কিছুই একটি অবজেক্ট (), সুতরাং "কেবলমাত্র বস্তুগুলিতে এটি ব্যবহার করুন" এর মতো বিবৃতি কিছুটা বিভ্রান্তিকর। এছাড়াও জাভাস্ক্রিপ্টটি দৃ strongly়ভাবে টাইপ করা হয় না যাতে 1 == "1" সত্য (যদিও 1 === "1" নয়, এতে ক্রকফোর্ড বড়)। জেএসে অ্যারেগুলির প্রোগোম্যাটিক ধারণাটি আসে, সংজ্ঞাটিতে টাইপিং গুরুত্বপূর্ণ important

@ ব্রেন্টন - পরিভাষা স্বৈরশাসক হওয়ার দরকার নেই; "এসোসিয়েটিভ অ্যারে", "ডিকশনারি", "হ্যাশ", "অবজেক্ট", এই প্রোগ্রামিং কনসেপ্টগুলি জেএসের একটি কাঠামোর জন্য প্রযোজ্য। এটি নাম (কী, সূচক) মান জোড়া, যেখানে মানটি অন্য কোনও বস্তু হতে পারে (স্ট্রিংগুলিও বস্তুগুলি)

সুতরাং, new Array()হিসাবে একই[]

new Object() প্রায় অনুরূপ {}

var myarray = [];

এমন একটি কাঠামো তৈরি করে যা এই বিধিনিষেধের সাথে অ্যারে হয় যে সমস্ত সূচী (ওরফে কী) অবশ্যই একটি সম্পূর্ণ সংখ্যা হতে হবে। এটি .push () এর মাধ্যমে নতুন সূচকগুলিকে স্বয়ংক্রিয়ভাবে নির্ধারণের অনুমতি দেয়

var myarray = ["one","two","three"];

সত্যিই সবচেয়ে ভাল মাধ্যমে মোকাবেলা করা হয় for(initialization;condition;update){

কিন্তু কি ব্যাপারে:

var myarray = [];
myarray[100] = "foo";
myarray.push("bar");

এটা চেষ্টা কর:

var myarray = [], i;
myarray[100] = "foo";
myarray.push("bar");
myarray[150] = "baz";
myarray.push("qux");
alert(myarray.length);
for(i in myarray){
    if(myarray.hasOwnProperty(i)){  
        alert(i+" : "+myarray[i]);
    }
}

সম্ভবত কোনও অ্যারের সেরা ব্যবহার নয়, তবে কেবল একটি চিত্র যা জিনিসগুলি সবসময় ক্লিয়ারকাট হয় না।

আপনি যদি কীগুলি জানেন এবং অবশ্যই সেগুলি পুরো সংখ্যা না হয়ে থাকে তবে আপনার স্ট্রাকচার বিকল্পের মতো অ্যারেটি হ'ল অবজেক্ট।

var i, myarray= {
   "first":"john",
   "last":"doe",
   100:"foo",
   150:"baz"
};
for(i in myarray){
    if(myarray.hasOwnProperty(i)){  
        alert(i+" : "+myarray[i]);
    }
}

"কেবলমাত্র বস্তুগুলিতে এটি ব্যবহার করুন" এর অর্থ এটি অ্যারে বা অবজেক্টটিকে প্রসারিত এমন কোনও কিছুর উপরে ব্যবহার করবেন না, অন্যথায় আপনি যেমন উল্লেখ করেছেন, এটি খুব নিরীহ হবে যেহেতু সবকিছু অবজেক্টকে প্রসারিত করে
জুয়ান মেন্ডেস

'"এসোসিয়েটিভ অ্যারে", "অভিধান", "হ্যাশ", "অবজেক্ট", এই প্রোগ্রামিং কনসেপ্টগুলি জেএসের একটি কাঠামোর জন্য প্রযোজ্য।' না। তারা একে অপরের সাথে সাদৃশ্য সহ বিভিন্ন ভাষা থেকে ভিন্ন ধারণা । তবে আপনি যদি ধরে নিচ্ছেন যে সেগুলি / ঠিক একই / এবং একই উদ্দেশ্যে ব্যবহৃত হচ্ছে, একই উদ্দেশ্যে, আপনি কীভাবে ভাষা সম্পর্কে কম অজ্ঞতার দ্বারা এড়াতে পারবেন এমন কিছু সত্যই বোকা ভুল করার জন্য নিজেকে প্রস্তুত করছেন আপনি কাজ ব্যবহার করছেন।
ব্রেটন

2

অবশ্যই এটি বলার জন্য কিছুটা চরম

... কোনও অ্যারের উপরে গণনার জন্য কখনই ইন ইন লুপ ব্যবহার করবেন না। কখনও। এর জন্য ভাল পুরানো ব্যবহার করুন (ভেরি i = 0; i <অস্থির দৈর্ঘ্য; i ++)

?

এটি ডগলাস ক্রকফোর্ড এক্সট্রাক্টের অংশটি হাইলাইট করার মতো

... দ্বিতীয় রূপটি অবজেক্টগুলির সাথে ব্যবহার করা উচিত ...

যদি আপনার যদি কোনও এসোসিয়েটিভ অ্যারে (ওরফে হ্যাশটেবল / ডিকশনারি) প্রয়োজন হয় যেখানে সংখ্যার ভিত্তিতে ইনডেক্সের পরিবর্তে চাবিগুলির নাম দেওয়া হয়েছে, আপনাকে এটি কোনও অবজেক্ট হিসাবে প্রয়োগ করতে হবে, যেমন var myAssocArray = {key1: "value1", key2: "value2"...};

এই ক্ষেত্রে myAssocArray.lengthনাল আসতে হবে (কারণ এই বস্তু একটি 'length' প্রোপার্টি নেই), এবং আপনার i < myAssocArray.lengthইচ্ছার আপনি খুব দূরে নয় পেতে। বৃহত্তর সুবিধার্থে সরবরাহ করার পাশাপাশি, আমি আশা করব যে অ্যা্যাসোসিয়েটিভ অ্যারেগুলি অনেক পরিস্থিতিতে পারফরম্যান্স সুবিধা দেয়, কারণ অ্যারে কীগুলি দরকারী বৈশিষ্ট্য হতে পারে (যেমন একটি অ্যারে সদস্যের আইডি সম্পত্তি বা নাম), যার অর্থ আপনাকে দীর্ঘায়িত হতে হবে না অ্যারে বারবার মূল্যায়ন করে যদি বিবৃতিগুলি আপনার পরে থাকে এমন অ্যারে এন্ট্রিটি খুঁজে বের করে।

যাইহোক, জেএসলিন্ট ত্রুটি বার্তাগুলির ব্যাখ্যার জন্যও ধন্যবাদ, আমার অগণিত এসোসিয়েটিভ অ্যারেগুলির মাধ্যমে ইন্টারঅ্যাক্ট করার সময় আমি এখন 'isOwNProperty' চেক ব্যবহার করব!


1
আপনি গভীর বিভ্রান্ত। জাভাস্ক্রিপ্টে "এসোসিয়েটিভ অ্যারে" বলে কোনও জিনিস নেই। এটি কঠোরভাবে একটি পিএইচপি ধারণা।
ব্রেটন

এটি সত্য যে এই জিনিসগুলির কোনও lengthসম্পত্তি নেই তবে আপনি এটি অন্য উপায়ে করতে পারেন:var myArr = []; myArr['key1'] = 'hello'; myArr['key2'] = 'world';
nyuszika7h

3
@ Nyuszika7H এটি ভুল উপায়। আপনার যদি পূর্ণসংখ্যার সূচকযুক্ত অ্যারের প্রয়োজন না হয় তবে আপনার ব্যবহার করা উচিত নয় var myArr = [], এটি var myArr = {}পিএইচপিতে হওয়া উচিত তারা একই জিনিস, তবে জেএসে নয়।
জুয়ান মেন্ডেস

সংঘবদ্ধ "অ্যারে" কোনও অ্যারে নয়।
ভিনসেন্ট ম্যাকনাব


0

প্রতিটি / ইন / ফর / $ প্রতিটি বিষয়ের জন্য কেবল যুক্ত করতে আমি $ .এচ বনাম ইন: http://jsperf.com/each-vs-for-in/2 ব্যবহারের জন্য একটি জেএসপিআইপি পরীক্ষার কেস যুক্ত করেছি http://

বিভিন্ন ব্রাউজার / সংস্করণগুলি এটিকে ভিন্নভাবে পরিচালনা করে তবে এটি মনে হয় ea

আপনি যদি কোনও এসোসিয়েটিভ অ্যারে / অবজেক্টের মধ্য দিয়ে পুনরায় পুনঃব্যবস্থার জন্য ব্যবহার করছেন, আপনি কী করছেন তা জেনে এবং অন্য সমস্ত কিছু উপেক্ষা করে, যদি আপনি jQuery ব্যবহার করেন তবে কেবলমাত্র (এবং তারপরে একটি বিরতি; একবার ব্যবহার করার পরে) ব্যবহার করুন আপনি যা জানেন তা শেষ উপাদান হওয়া উচিত)

আপনি যদি প্রতিটি কী জুটির সাথে এটির জন্য কিছু সম্পাদন করতে অ্যারের মাধ্যমে পুনরাবৃত্তি করে থাকেন তবে আপনি jQuery ব্যবহার না করলে হ্যাশঅনপ্রোপার্টি পদ্ধতিটি ব্যবহার করা উচিত এবং আপনি jQuery ব্যবহার না করেন $ ব্যবহার করুন ch

for(i=0;i<o.length;i++)আপনার যদি কোনও এসোসিয়েটিভ অ্যারের প্রয়োজন না হয় তবে সর্বদা ব্যবহার করুন ... লল ক্রোম পারফরম্যান্স করেছে যা ইন বা এর চেয়ে 97% দ্রুত faster$.each

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.