কীভাবে একটি জাভাস্ক্রিপ্ট অবজেক্টটি দ্রুত সাফ করবেন?


170

একটি জাভাস্ক্রিপ্ট অ্যারে দিয়ে, আমি এটিকে একটি একক দায়িত্ব সহ খালি অবস্থায় পুনরায় সেট করতে পারি:

array.length = 0;

এটি অ্যারেটিকে "উপস্থিত" খালি এবং পুনঃব্যবহারের জন্য প্রস্তুত করে তোলে এবং আমি যতদূর বুঝতে পারি এটি একটি একক "অপারেশন" - যা স্থির সময়।

জেএস অবজেক্টটি সাফ করার মতো কোনও উপায় আছে? আমি জানি আমি এর ক্ষেত্রগুলি মুছে ফেলাতে পুনরাবৃত্তি করতে পারি:

for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } }

তবে এটির লিনিয়ার জটিলতা রয়েছে।

আমি কেবলমাত্র বস্তুকে ফেলে দিতে এবং একটি নতুন তৈরি করতে পারি:

obj = {};

তবে নতুন বস্তুর "প্রতিশ্রুতিবদ্ধ" সৃষ্টি আইই 6-তে বর্জ্য সংগ্রহের ক্ষেত্রে সমস্যা দেখা দেয়। ( এখানে বর্ণিত হিসাবে )


2
"অ্যারে.লেন্থ == 0 ... হ'ল একক 'অপারেশন' - যা ধ্রুবক সময়" - আমি সন্দেহ করি।
মাইলস

1
আমি বিশ্বাস করি না যে এটি কোনও লিখিত সামগ্রী মুছে ফেলেছে - কেবল ধাক্কা () কাজ করার মতো করে তোলে যেমন অ্যারেটি খালি ছিল। বিপরীতটি সত্য হওয়ার কোনও রেফারেন্স আপনার কাছে রয়েছে?
লেভিক

2
@ডারবার্ট: এটি কিছুটা অহঙ্কারী। আই 6 G আবর্জনা সংগ্রহের সমস্যাটি ভালভাবে নথিভুক্ত।
লেভিক

মূল পোস্টে কোডটি ভুল। অভ্যন্তরীণ লুপটি হওয়া উচিত: আপত্তি [প্রপ] মুছুন। আমার পোস্টিং stackoverflow.com/questions/6780315/… দেখুন
stackoverflowuser2010

6
যেহেতু এই স্নিপেট ব্যবহার করছেন, তার জন্যfor (var prop in obj)
bendytree

উত্তর:


54

আপনার প্রশ্নের সংক্ষিপ্ত উত্তর, আমি মনে করি, এটি হ'ল না (আপনি কেবল একটি নতুন অবজেক্ট তৈরি করতে পারবেন)।

  1. এই উদাহরণে, আমি বিশ্বাস করি যে দৈর্ঘ্য 0 নির্ধারণ করা এখনও আবর্জনা সংগ্রহের জন্য সমস্ত উপাদানকে রেখে দেয়।

  2. আপনি এটি অবজেক্ট.প্রোটোটাইপটিতে যুক্ত করতে পারেন যদি এটি এমন কিছু হয় যা আপনি প্রায়শই ব্যবহার করেন। হ্যাঁ এটি জটিলতায় রৈখিক, তবে আবর্জনা সংগ্রহ না করে এমন কিছু পরে যাবে।

  3. এটিই সেরা সমাধান। আমি জানি এটি আপনার প্রশ্নের সাথে সম্পর্কিত নয় - তবে কতক্ষণ আমাদের আইআই 6 সমর্থন করা চালিয়ে যেতে হবে? এটির ব্যবহার বন্ধ করার জন্য প্রচুর প্রচারণা রয়েছে।

উপরে কিছু ভুল থাকলে আমাকে সংশোধন করতে দ্বিধা বোধ করবেন।


4
কিছু সংস্থাকে আইআই 6 কে নীতি সম্পর্কিত হিসাবে সমর্থন করতে হয় - এবং এটি দ্বিগুণ অঙ্কের বাজারের অংশীদারিত্ব প্রাপ্ত হওয়ার পরেও করবে। আইসির জিসি সমস্যাটি এমন নয় যে জিনিসগুলি অবিচ্ছিন্ন হয়ে যায়, এটি হ'ল সংগ্রহটি প্রতিটি এক্স বরাদ্দ চালায় এবং প্রতিবার বেশি সময় নেয়। সুতরাং বস্তু পুনরায় ব্যবহার করার প্রয়োজন।
লেভিক

হ্যাঁ, এমন অনেকগুলি মামলা রয়েছে যেখানে এখনও এটি কোম্পানির নীতি / ইত্যাদি কারণে ব্যবহৃত হয় used তবুও আমি বিষয় র‍্যাঙ্কিংয়ের বাইরে ছিলাম :) সুতরাং কীভাবে আপত্তি.পর্প মুছবে না; সম্পত্তি নিজেই একটি বস্তু হয় যখন সম্পাদন? আপনি যদি সেখানে খুব দক্ষতা অর্জন করেন তা আমি জানি না।
jthompson

2
দুর্বল জিসির অর্থ আই 6 slow ধীর গতিতে চলবে, এর অর্থ হ'ল আপগ্রেড করার আরও বেশি উত্সাহ রয়েছে। আপনি এখনও এটি সমর্থন করছেন, এটি কেবল ধীরে চলবে।
নিকফ

1
এর অর্থ আপনার অ্যাপ্লিকেশনটি আপনার লক্ষ্যযুক্ত দর্শকদের একটি অংশের জন্য খারাপ অভিনয় করে ly কিছু লোকের কাছে আপগ্রেড করার বিকল্প নেই কারণ তারা নিয়ন্ত্রিত আইটি পরিবেশে রয়েছে। সম্ভবত তাদের সংস্থাটি একটি অ্যাক্টিভ-এক্স নিয়ন্ত্রণ ব্যবহার করে যা কেবল আই 6 এর সাথে কাজ করে।
লেভিক

2
@ লিভিক কেবল এমন একটি প্রতিষ্ঠানের পক্ষে কাজ করবেন না যা আপনাকে আই 6 সমর্থন করতে বাধ্য করে। এটি যাইহোক ভাল সংস্থা হতে পারে না।
নিম্ন_প্রতিক্রিয়া

121

ভাল, জিনিস খুব সহজ করার ঝুঁকিতে ...

for (var member in myObject) delete myObject[member];

... নূন্যতম ভীতিজনক বন্ধনী সহ কোডের এক লাইনে অবজেক্টটি পরিষ্কার করতে বেশ কার্যকর বলে মনে হচ্ছে। সমস্ত সদস্য আবর্জনা হিসাবে বাম পরিবর্তে সত্যই মুছে ফেলা হবে।

স্পষ্টতই যদি আপনি অবজেক্টটি নিজেই মুছতে চান তবে তার জন্য আপনাকে একটি পৃথক মুছে ফেলতে হবে ()।


2
মুছে ফেলা কেবলমাত্র রেফারেন্সকেই ভেঙে দেয়, উদাহরণস্বরূপ এটি মাইবজেক্ট [সদস্য] অপরিজ্ঞাতকে মূল্যায়ন করে তোলে এবং প্রযুক্তিগতভাবে অবজেক্টটিকে আবর্জনা হিসাবে ছেড়ে দেয় যদি না অবজেক্টের সাথে অন্য রেফারেন্স উপস্থিত থাকে।
জোয়ে কারসন

এই উত্তর খুব দায়ী। যদি কোনও নিষ্পত্তি পর্যায়ে সমস্ত পরিচালিত অবজেক্টগুলিতে প্রয়োগ করা হয় তবে এটি সাধারণত দুর্ঘটনাক্রমে অবজেক্ট চেইনের অনেকের যত্ন নেবে।
উইটজে

1
ওপি এই লুপটিতে ব্যবহারের পরামর্শ দেয় hasOwnProperty। আমি ডকগুলি পড়েছি, তবে আমি এখনও আমার মাথাটি গুটিয়ে নেওয়ার চেষ্টা করছি যদি আমরা hasOwnProperty()চেক বাদ দিই তবে ঝুঁকিগুলি কী?
লজিডেলিক

2
আমি ভেবেছিলাম অবজেক্টের উপর পুনরাবৃত্তি করার সময় সম্পত্তিগুলি মুছে ফেলা বিপজ্জনক - বেশিরভাগ ভাষায় এটি পুনরুক্তিটিকে অকার্যকর করে এবং জিনিসগুলিকে সূক্ষ্মভাবে বা বিপর্যয়করভাবে ভেঙে দেবে - তবে এমডিএন প্রতি জাভাস্ক্রিপ্টে দৃশ্যত এটি ঠিক আছে: "এমন একটি সম্পত্তি যা আগে মুছে ফেলা হয় এটি পরিদর্শন করা হয়েছে পরে আর পরিদর্শন করা হবে না। " বিকাশকারী.মোজিলা.আর.ইন-
পিয়োটার

46

ES5

ES5 সমাধান হতে পারে:

// for enumerable and non-enumerable properties
Object.getOwnPropertyNames(obj).forEach(function (prop) {
  delete obj[prop];
});

ES6

এবং ES6 সমাধান হতে পারে:

// for enumerable and non-enumerable properties
for (const prop of Object.getOwnPropertyNames(obj)) {
  delete obj[prop];
}

কর্মক্ষমতা

চশমা নির্বিশেষে, দ্রুত সমাধানগুলি সাধারণত:

// for enumerable and non-enumerable of an object with proto chain
var props = Object.getOwnPropertyNames(obj);
for (var i = 0; i < props.length; i++) {
  delete obj[props[i]];
}

// for enumerable properties of shallow/plain object
for (var key in obj) {
  // this check can be safely omitted in modern JS engines
  // if (obj.hasOwnProperty(key))
    delete obj[key];
}

কেবল for..inঅগভীর বা সরল বস্তুতে সম্পাদন করার কারণ হ'ল এটি মুখ্য বৈশিষ্ট্যগুলি মুছে ফেলতে পারে না কেবল প্রোটোটাইপিকভাবে উত্তরাধিকার সূত্রে প্রাপ্ত বৈশিষ্ট্যগুলি অনুসরণ করে। ক্ষেত্রে এটি নিশ্চিত জানা যায়নি যে একটি বস্তু প্লেইন এবং সম্পত্তি, গণনীয় হয় forসঙ্গে Object.getOwnPropertyNamesএকটি উন্নততর পছন্দ।


7

আপনি এটি চেষ্টা করতে পারেন। নীচের ফাংশনটি অবজেক্টের বৈশিষ্ট্যের সমস্ত মানকে অপরিজ্ঞাত করে দেয়। নেস্টেড অবজেক্টগুলির সাথে কাজ করে।

var clearObjectValues = (objToClear) => {
    Object.keys(objToClear).forEach((param) => {
        if ( (objToClear[param]).toString() === "[object Object]" ) {
            clearObjectValues(objToClear[param]);
        } else {
            objToClear[param] = undefined;
        }
    })
    return objToClear;
};

ক্ষেত্রগুলি কেবল অপরিজ্ঞাত হিসাবে সেট করা আছে বলে নোট করুন এটি সময়ের সাথে সাথে মেমরি ফাঁসের কারণ হিসাবে আবর্জনা সংগ্রহকারী ক্ষেত্রগুলি সাফ করবেন না।
অ্যালেক্সিস টাইলার

7

সুতরাং আপনার প্রশ্নটি পুনরুদ্ধার করতে: আপনি IE6 জিসি বাগের সাথে যতটা সম্ভব সমস্যাটি এড়াতে চান। এই বাগের দুটি কারণ রয়েছে:

  1. এতগুলি বরাদ্দে একবারে আবর্জনা সংগ্রহ ঘটে ; অতএব, আপনি যত বেশি বরাদ্দ রাখবেন, প্রায়শই জিসি চলবে;
  2. আপনি 'বাতাসে' যত বেশি জিনিস পেয়েছেন, প্রতিটি আবর্জনা সংগ্রহের সময় রান করতে তত বেশি সময় লাগে (যেহেতু এটি আবর্জনা হিসাবে চিহ্নিত রয়েছে তা দেখার জন্য এটি সামগ্রীর পুরো তালিকাতে ক্রল করবে)।

1 টির সমাধানটি মনে হয়: বরাদ্দের সংখ্যা কম রাখুন; নতুন অবজেক্ট এবং স্ট্রিং যত তাড়াতাড়ি সম্ভব বরাদ্দ করুন।

2 টির সমাধানটি মনে হয়: 'লাইভ' অবজেক্টের সংখ্যা কম রাখুন; আপনার স্ট্রিং এবং অবজেক্টগুলি আর আপনার প্রয়োজন না হওয়ার সাথে সাথে মুছুন এবং যখন প্রয়োজন তখন এগুলি নতুন করে তৈরি করুন।

একটি নির্দিষ্ট পরিমাণে, এই সমাধানগুলি পরস্পরবিরোধী: স্মৃতিতে অবজেক্টের সংখ্যা কম রাখলে আরও বেশি বরাদ্দ এবং ডি-বরাদ্দের প্রয়োজন হয়। বিপরীতভাবে, ক্রমাগত একই জিনিসগুলির পুনঃব্যবহারের অর্থ কঠোরভাবে প্রয়োজনের চেয়ে স্মৃতিতে আরও বেশি জিনিস রাখা could


এখন আপনার প্রশ্নের জন্য। আপনি কোনও নতুন তৈরি করে বা এর সমস্ত বৈশিষ্ট্য মুছে ফেলার মাধ্যমে কোনও বস্তু পুনরায় সেট করবেন কিনা: এটি পরবর্তী সময়ে আপনি এটি করতে চাইলে তার উপর নির্ভর করবে।

আপনি সম্ভবত এটিতে নতুন বৈশিষ্ট্য বরাদ্দ করতে চাইবেন:

  • আপনি যদি তাৎক্ষণিকভাবে এটি করেন, তবে আমি সরাসরি নতুন বৈশিষ্ট্যগুলি বরাদ্দ করার পরামর্শ দিচ্ছি এবং প্রথমে মুছে ফেলা বা সাফ করা বাদ দিন। (নিশ্চিত করুন যে সমস্ত বৈশিষ্ট্য হয় ওভাররাইট বা মুছে ফেলা হয়েছে, যদিও!)
  • যদি অবজেক্টটি তাত্ক্ষণিকভাবে ব্যবহার না করা হয় তবে পরে কিছু পর্যায়ে পুনরায় সজ্জিত করা হয় তবে আমি এটি মুছতে বা এটি বাতিল করার পরামর্শ দিই এবং পরে একটি নতুন তৈরি করব।

কোনও নতুন তৈরি না করে পুনরায় ব্যবহারের জন্য জেএসক্রিপ্ট অবজেক্টটি সাফ করার জন্য কোন দ্রুত, সহজ ব্যবহারের উপায় নেই। যার অর্থ আপনার প্রশ্নের সংক্ষিপ্ত উত্তর হ'ল 'না', যেমন জঠম্পসন বলেছেন।


4

ES7 এ অবজেক্ট.অভিজারের প্রত্যাশায় এবং সাধারণভাবে ডেটা-বাঁধাইয়ের সাথে নতুন কিছু চিন্তা করার জন্য। বিবেচনা:

var foo={
   name: "hello"
};

Object.observe(foo, function(){alert('modified');}); // bind to foo

foo={}; // You are no longer bound to foo but to an orphaned version of it
foo.name="there"; // This change will be missed by Object.observe()

সুতরাং যে পরিস্থিতিতে # 2 সেরা পছন্দ হতে পারে।


অ্যাংুলারজেএস এর মতো ফ্রেমওয়ার্কগুলি যদি অবজেক্টগুলিকে দৃশ্যের সাথে আবদ্ধ করতে পারে (এক বা দুটি উপায় বাঁধাই করা যায়), তবে ক্লিয়ারিং অবজেক্ট obj = {}ফ্রেমওয়ার্কটি অবজেক্টে আরও কোনও পরিবর্তন সম্পর্কে অসচেতন করে তোলে তাই আপনার টেমপ্লেটগুলি যথাযথভাবে রেন্ডার হবে না। বিকল্প # 2 তবে সঠিকভাবে কাজ করবে।
ইভান হুঞ্জাক

ভাল যুক্তি. আমার একই হিপ অবজেক্টটি রাখা দরকার এবং এটি একই কারণটি দেখায় যে আপনি একই রেফারেন্স রাখতে চান।
কোডি

1

আপনি প্রপস মুছতে পারেন, তবে ভেরিয়েবল মুছবেন না। delete abc;ES5 এ অবৈধ (এবং ব্যবহারের সাথে কঠোরভাবে ছোঁড়ে)

আপনি এটি জিসিতে মুছে ফেলার জন্য সেটটি বাতিল করতে নির্ধারণ করতে পারেন (এটি যদি আপনার বৈশিষ্ট্যের অন্যান্য উল্লেখ থাকে না)

lengthকোনও বস্তুর উপর সম্পত্তি সেট করা কোনও পরিবর্তন করে না। (এটি কেবল, ভাল, সম্পত্তি সেট করে)


পরিষ্কার হওয়ার জন্য, lengthঅ্যারেতে 0 এ সেট করার সময় (যা নির্দিষ্ট ধরণের অবজেক্ট - যদি আপনি আমাকে বিশ্বাস না করেন, চালানোর চেষ্টা করুন typeof []), এটি কেবল সম্পত্তি সেট করে না, এটি আসলে অ্যারের সামগ্রীগুলি পরিষ্কার করে দেবে । স্ট্যাকওভারফ্লো.com
বিন বিন

ঠিক আছে, আপনি মুছে ফেলতে বলতে পারেন window.abcকারণ এটি সেই ক্ষেত্রে প্রপস।
শেদ্রিচ

0

এটি আমাকে যুগে যুগে বগড করেছে তাই এখানে আমার সংস্করণটি হ'ল আমি কোনও খালি বস্তু চাইনি, আমি সমস্ত বৈশিষ্ট্য সহ একটি চাইছিলাম তবে কিছু ডিফল্ট মানটিতে পুনরায় সেট করলাম। এক শ্রেণীর নতুন ইনস্ট্যান্টেশনের মতো।

let object1 = {
  a: 'somestring',
  b: 42,
  c: true,
  d:{
    e:1,
    f:2,
    g:true,
    h:{
      i:"hello"
    }
  },
  j: [1,2,3],
  k: ["foo", "bar"],
  l:["foo",1,true],
  m:[{n:10, o:"food", p:true }, {n:11, o:"foog", p:true }],
  q:null,
  r:undefined
};

let boolDefault = false;
let stringDefault = "";
let numberDefault = 0;

console.log(object1);
//document.write("<pre>");
//document.write(JSON.stringify(object1))
//document.write("<hr />");
cleanObject(object1);
console.log(object1);
//document.write(JSON.stringify(object1));
//document.write("</pre>");

function cleanObject(o) {
  for (let [key, value] of Object.entries(o)) {
    let propType = typeof(o[key]);

    //console.log(key, value, propType);

    switch (propType) {
      case "number" :
        o[key] = numberDefault;
        break;

      case "string":
        o[key] = stringDefault;
        break;

      case "boolean":
        o[key] = boolDefault;    
        break;

      case "undefined":
        o[key] = undefined;   
        break;

      default:
        if(value === null) {
            continue;
        }

        cleanObject(o[key]);
        break;
    }
  }
}

// EXPECTED OUTPUT
// Object { a: "somestring", b: 42, c: true, d: Object { e: 1, f: 2, g: true, h: Object { i: "hello" } }, j: Array [1, 2, 3], k: Array ["foo", "bar"], l: Array ["foo", 1, true], m: Array [Object { n: 10, o: "food", p: true }, Object { n: 11, o: "foog", p: true }], q: null, r: undefined }
// Object { a: "", b: 0, c: undefined, d: Object { e: 0, f: 0, g: undefined, h: Object { i: "" } }, j: Array [0, 0, 0], k: Array ["", ""], l: Array ["", 0, undefined], m: Array [Object { n: 0, o: "", p: undefined }, Object { n: 0, o: "", p: undefined }], q: null, r: undefined }

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