অ্যারে পরিবর্তনগুলি কীভাবে দেখবেন?


111

জাভাস্ক্রিপ্টে, ধাক্কা, পপ, শিফট বা সূচক-ভিত্তিক অ্যাসাইনমেন্ট ব্যবহার করে কোনও অ্যারে সংশোধিত করার জন্য কি কোনও উপায় অবহিত করার উপায় আছে? আমি এমন কিছু চাই যা এমন একটি ইভেন্ট আগুন যা আমি পরিচালনা করতে পারি।

আমি watch()স্পাইডারমনকির কার্যকারিতা সম্পর্কে জানি তবে এটি কেবল তখন কার্যকর হয় যখন পুরো ভেরিয়েবলটি অন্য কোনওটিতে সেট করা থাকে।

উত্তর:


174

কয়েকটি অপশন আছে...

1. পুশ পদ্ধতিটি ওভাররাইড করুন

দ্রুত এবং নোংরা রুটে গিয়ে আপনি আপনার অ্যারে 1 এর জন্য `পুশ ()` পদ্ধতিটি ওভাররাইড করতে পারেন :
Object.defineProperty(myArray, "push", {
  enumerable: false, // hide from for...in
  configurable: false, // prevent further meddling...
  writable: false, // see above ^
  value: function () {
    for (var i = 0, n = this.length, l = arguments.length; i < l; i++, n++) {          
      RaiseMyEvent(this, n, this[n] = arguments[i]); // assign/raise your event
    }
    return n;
  }
});

1 বিকল্পভাবে, আপনি যদি সমস্ত অ্যারে লক্ষ্যবস্তু করতে চান তবে আপনি ওভাররাইড করতে পারেন Array.prototype.push()। সতর্কতা ব্যবহার করুন, যদিও; আপনার পরিবেশের অন্যান্য কোডগুলি এ জাতীয় পরিবর্তন পছন্দ করতে বা আশা করতে পারে না। এখনও, যদি একটি ক্যাচ-সব শব্দ মর্মস্পর্শী শুধু প্রতিস্থাপন myArrayসঙ্গে Array.prototype

এখন, এটি কেবল একটি পদ্ধতি এবং অ্যারে সামগ্রী পরিবর্তন করার প্রচুর উপায় রয়েছে। আমাদের সম্ভবত আরও বিস্তৃত কিছু দরকার ...

2. একটি কাস্টম পর্যবেক্ষণযোগ্য অ্যারে তৈরি করুন

ওভাররাইডিং পদ্ধতিগুলির পরিবর্তে, আপনি নিজের পর্যবেক্ষণযোগ্য অ্যারে তৈরি করতে পারেন। এই নির্দিষ্ট প্রয়োগটি একটি অ্যারেটিকে নতুন অ্যারে-জাতীয় বস্তুতে অনুলিপি করে এবং কাস্টম `পুশ ()`, `পপ ()`, `শিফ্ট ()`, ইউনশিফ্ট () `,` স্লাইস () `, এবং স্প্লাইস সরবরাহ করে ( ) `পদ্ধতিগুলি ** পাশাপাশি ** কাস্টম সূচক অ্যাক্সেসরগুলি (শর্তযুক্ত আকারটি কেবল পূর্বোক্ত পদ্ধতিগুলির মধ্যে একটি বা` দৈর্ঘ্যের সম্পত্তি দ্বারা পরিবর্তিত হয়)।

function ObservableArray(items) {
  var _self = this,
    _array = [],
    _handlers = {
      itemadded: [],
      itemremoved: [],
      itemset: []
    };

  function defineIndexProperty(index) {
    if (!(index in _self)) {
      Object.defineProperty(_self, index, {
        configurable: true,
        enumerable: true,
        get: function() {
          return _array[index];
        },
        set: function(v) {
          _array[index] = v;
          raiseEvent({
            type: "itemset",
            index: index,
            item: v
          });
        }
      });
    }
  }

  function raiseEvent(event) {
    _handlers[event.type].forEach(function(h) {
      h.call(_self, event);
    });
  }

  Object.defineProperty(_self, "addEventListener", {
    configurable: false,
    enumerable: false,
    writable: false,
    value: function(eventName, handler) {
      eventName = ("" + eventName).toLowerCase();
      if (!(eventName in _handlers)) throw new Error("Invalid event name.");
      if (typeof handler !== "function") throw new Error("Invalid handler.");
      _handlers[eventName].push(handler);
    }
  });

  Object.defineProperty(_self, "removeEventListener", {
    configurable: false,
    enumerable: false,
    writable: false,
    value: function(eventName, handler) {
      eventName = ("" + eventName).toLowerCase();
      if (!(eventName in _handlers)) throw new Error("Invalid event name.");
      if (typeof handler !== "function") throw new Error("Invalid handler.");
      var h = _handlers[eventName];
      var ln = h.length;
      while (--ln >= 0) {
        if (h[ln] === handler) {
          h.splice(ln, 1);
        }
      }
    }
  });

  Object.defineProperty(_self, "push", {
    configurable: false,
    enumerable: false,
    writable: false,
    value: function() {
      var index;
      for (var i = 0, ln = arguments.length; i < ln; i++) {
        index = _array.length;
        _array.push(arguments[i]);
        defineIndexProperty(index);
        raiseEvent({
          type: "itemadded",
          index: index,
          item: arguments[i]
        });
      }
      return _array.length;
    }
  });

  Object.defineProperty(_self, "pop", {
    configurable: false,
    enumerable: false,
    writable: false,
    value: function() {
      if (_array.length > -1) {
        var index = _array.length - 1,
          item = _array.pop();
        delete _self[index];
        raiseEvent({
          type: "itemremoved",
          index: index,
          item: item
        });
        return item;
      }
    }
  });

  Object.defineProperty(_self, "unshift", {
    configurable: false,
    enumerable: false,
    writable: false,
    value: function() {
      for (var i = 0, ln = arguments.length; i < ln; i++) {
        _array.splice(i, 0, arguments[i]);
        defineIndexProperty(_array.length - 1);
        raiseEvent({
          type: "itemadded",
          index: i,
          item: arguments[i]
        });
      }
      for (; i < _array.length; i++) {
        raiseEvent({
          type: "itemset",
          index: i,
          item: _array[i]
        });
      }
      return _array.length;
    }
  });

  Object.defineProperty(_self, "shift", {
    configurable: false,
    enumerable: false,
    writable: false,
    value: function() {
      if (_array.length > -1) {
        var item = _array.shift();
        delete _self[_array.length];
        raiseEvent({
          type: "itemremoved",
          index: 0,
          item: item
        });
        return item;
      }
    }
  });

  Object.defineProperty(_self, "splice", {
    configurable: false,
    enumerable: false,
    writable: false,
    value: function(index, howMany /*, element1, element2, ... */ ) {
      var removed = [],
          item,
          pos;

      index = index == null ? 0 : index < 0 ? _array.length + index : index;

      howMany = howMany == null ? _array.length - index : howMany > 0 ? howMany : 0;

      while (howMany--) {
        item = _array.splice(index, 1)[0];
        removed.push(item);
        delete _self[_array.length];
        raiseEvent({
          type: "itemremoved",
          index: index + removed.length - 1,
          item: item
        });
      }

      for (var i = 2, ln = arguments.length; i < ln; i++) {
        _array.splice(index, 0, arguments[i]);
        defineIndexProperty(_array.length - 1);
        raiseEvent({
          type: "itemadded",
          index: index,
          item: arguments[i]
        });
        index++;
      }

      return removed;
    }
  });

  Object.defineProperty(_self, "length", {
    configurable: false,
    enumerable: false,
    get: function() {
      return _array.length;
    },
    set: function(value) {
      var n = Number(value);
      var length = _array.length;
      if (n % 1 === 0 && n >= 0) {        
        if (n < length) {
          _self.splice(n);
        } else if (n > length) {
          _self.push.apply(_self, new Array(n - length));
        }
      } else {
        throw new RangeError("Invalid array length");
      }
      _array.length = n;
      return value;
    }
  });

  Object.getOwnPropertyNames(Array.prototype).forEach(function(name) {
    if (!(name in _self)) {
      Object.defineProperty(_self, name, {
        configurable: false,
        enumerable: false,
        writable: false,
        value: Array.prototype[name]
      });
    }
  });

  if (items instanceof Array) {
    _self.push.apply(_self, items);
  }
}

(function testing() {

  var x = new ObservableArray(["a", "b", "c", "d"]);

  console.log("original array: %o", x.slice());

  x.addEventListener("itemadded", function(e) {
    console.log("Added %o at index %d.", e.item, e.index);
  });

  x.addEventListener("itemset", function(e) {
    console.log("Set index %d to %o.", e.index, e.item);
  });

  x.addEventListener("itemremoved", function(e) {
    console.log("Removed %o at index %d.", e.item, e.index);
  });
 
  console.log("popping and unshifting...");
  x.unshift(x.pop());

  console.log("updated array: %o", x.slice());

  console.log("reversing array...");
  console.log("updated array: %o", x.reverse().slice());

  console.log("splicing...");
  x.splice(1, 2, "x");
  console.log("setting index 2...");
  x[2] = "foo";

  console.log("setting length to 10...");
  x.length = 10;
  console.log("updated array: %o", x.slice());

  console.log("setting length to 2...");
  x.length = 2;

  console.log("extracting first element via shift()");
  x.shift();

  console.log("updated array: %o", x.slice());

})();

রেফারেন্সের জন্য দেখুন ।Object.defineProperty()

এটি আমাদের কাছাকাছি পৌঁছেছে কিন্তু এটি এখনও বুলেট প্রুফ নয় ... যা আমাদের এনেছে:

3. প্রক্সি

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

এখানে একটি প্রত্যাহার নিচে নমুনা:

(function() {

  if (!("Proxy" in window)) {
    console.warn("Your browser doesn't support Proxies.");
    return;
  }

  // our backing array
  var array = ["a", "b", "c", "d"];

  // a proxy for our array
  var proxy = new Proxy(array, {
    apply: function(target, thisArg, argumentsList) {
      return thisArg[target].apply(this, argumentList);
    },
    deleteProperty: function(target, property) {
      console.log("Deleted %s", property);
      return true;
    },
    set: function(target, property, value, receiver) {      
      target[property] = value;
      console.log("Set %s to %o", property, value);
      return true;
    }
  });

  console.log("Set a specific index..");
  proxy[0] = "x";

  console.log("Add via push()...");
  proxy.push("z");

  console.log("Add/remove via splice()...");
  proxy.splice(1, 3, "y");

  console.log("Current state of array: %o", array);

})();


ধন্যবাদ! এটি নিয়মিত অ্যারে পদ্ধতিগুলির জন্য কাজ করে। "আরর [2] ="
ফু

4
আমি অনুমান করি আপনি set(index)অ্যারের প্রোটোটাইপটিতে কোনও পদ্ধতি প্রয়োগ করতে পারেন এবং বিরোধীদর্শিতার মতো কিছু করতে পারেন
পাবলো ফার্নান্দেজ

8
অ্যারে সাবক্লাস করা আরও ভাল হবে। অ্যারের প্রোটোটাইপটি পরিবর্তন করা সাধারণত ভাল ধারণা নয়।
ওয়েন

4
এখানে অসামান্য উত্তর। পর্যবেক্ষণযোগ্য অ্যারে ক্লাসটি দুর্দান্ত। +1
ডুবুর্ট

4
"'_আরআর.এলটি === 0 & নিজেকে মুছুন [সূচী];" - আপনি এই লাইন ব্যাখ্যা করতে পারেন?
স্প্লিন্টোর

23

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

এটি পদ্ধতির জন্য সাধারণ ধারণাটি আরও ভালভাবে চিত্রিত করে:

function processQ() {
   // ... this will be called on each .push
}

var myEventsQ = [];
myEventsQ.push = function() { Array.prototype.push.apply(this, arguments);  processQ();};

এটি ভাল ধারণা, তবে আপনি কি ভাবেন না যে উদাহরণস্বরূপ যদি আমি এটি চার্ট জেএস ডেটা অ্যারে প্রয়োগ করতে চাই এবং আমার কাছে 50 টি চার্ট রয়েছে যার অর্থ 50 অ্যারে এবং প্রতিটি অ্যারে প্রতি সেকেন্ডে আপডেট হবে -> এর আকারটি কল্পনা করুন দিন শেষে 'myEventsQ' অ্যারে! আমি মনে করি কখন এবং এখন এটিকে শিফট করা দরকার
ইয়াহিয়া

4
আপনি সমাধান বুঝতে পারেন না। myEventsQ অ্যারে (আপনার 50 টি অ্যারের মধ্যে একটি)। এই স্নিপেট অ্যারের আকার পরিবর্তন করে না, এবং কোনও অতিরিক্ত অ্যারে যোগ করে না, এটি কেবলমাত্র বিদ্যমান প্রোটোটাইপ পরিবর্তন করে।
সিচ

4
মিমি মিমি, আরও ব্যাখ্যা যদিও দেওয়া উচিত ছিল!
ইয়াহিয়া

4
pushlengthঅ্যারের ফেরত দেয় । সুতরাং, আপনি Array.prototype.push.applyএকটি ভেরিয়েবল দ্বারা ফিরে মান পেতে এবং এটি কাস্টম pushফাংশন থেকে ফিরে পেতে পারেন ।
আদিগা

12

আমি নিম্নলিখিতগুলি পেয়েছি যা এটি সম্পাদন করে বলে মনে হচ্ছে: https://github.com/mennovanslooten/Observable-Ararays

পর্যবেক্ষণযোগ্য-অ্যারেগুলি আন্ডারস্কোর প্রসারিত করে এবং নিম্নলিখিত হিসাবে ব্যবহার করা যেতে পারে: (সেই পৃষ্ঠা থেকে)

// For example, take any array:
var a = ['zero', 'one', 'two', 'trhee'];

// Add a generic observer function to that array:
_.observe(a, function() {
    alert('something happened');
});

13
এটি দুর্দান্ত, তবে একটি গুরুত্বপূর্ণ সতর্কতা রয়েছে: যখন একটি অ্যারের মত arr[2] = "foo"পরিবর্তন করা হয়, পরিবর্তনের বিজ্ঞপ্তিটি অ্যাসিনক্রোনাস । যেহেতু জেএস এই ধরণের পরিবর্তনগুলি দেখার কোনও উপায় সরবরাহ করে না, তাই এই লাইব্রেরি একটি সময়সীমা উপর নির্ভর করে যা প্রতি 250 এমএস চালায় এবং অ্যারেটি কোনও পরিবর্তন হয়েছে কিনা তা পরীক্ষা করে দেখুন - সুতরাং আপনি পরবর্তী সময় পর্যন্ত কোনও পরিবর্তন বিজ্ঞপ্তি পাবেন না সময়সীমা শেষ। তবে অন্যান্য পরিবর্তনগুলি push()তত্ক্ষণাত অবহিত করা হবে (একযোগে)
পিটারফ্লিন 18

6
এছাড়াও আমি অনুমান করি যে অ্যারে বড় হলে 250 ব্যবধান আপনার সাইটের পারফরম্যান্সকে প্রভাবিত করবে।
টম্যা জ্যাটো - মনিকা

সবে এটি ব্যবহার করা হয়েছে, কবজির মতো কাজ করে। আমাদের নোড-ভিত্তিক বন্ধুদের জন্য আমি একটি প্রতিশ্রুতি দিয়ে এই আগমনটি ব্যবহার করেছি comments প্রয়োজন ("আন্ডারস্কোর-অবজারভেশন") ( ); প্রতিশ্রুতি = প্রয়োজনীয় ("ব্লুবার্ড"); ফেরত নতুন প্রতিশ্রুতি (ফাংশন (সমাধান, প্রত্যাখ্যান) {রিটার্ন _.অবিজার (সারি, 'মুছুন', ফাংশন () {যদি ( .আইসেম্পটি (সারি)) {রিটার্ন রেজোলিউশন (ক্রিয়া);}});});
লাইফ

7

অ্যারে পরিবর্তনগুলি শুনতে আমি নিম্নলিখিত কোডটি ব্যবহার করেছি।

/* @arr array you want to listen to
   @callback function that will be called on any change inside array
 */
function listenChangesinArray(arr,callback){
     // Add more methods here if you want to listen to them
    ['pop','push','reverse','shift','unshift','splice','sort'].forEach((m)=>{
        arr[m] = function(){
                     var res = Array.prototype[m].apply(arr, arguments);  // call normal behaviour
                     callback.apply(arr, arguments);  // finally call the callback supplied
                     return res;
                 }
    });
}

আশা করি এটি কার্যকর ছিল :)


6

সবচেয়ে upvoted ওভাররাইড ধাক্কা পদ্ধতি @canon দ্বারা সমাধান কিছু পার্শ্ব প্রতিক্রিয়া যে আমার ক্ষেত্রে অসুবিধাজনক ছিল আছে:

  • এটি পুশ সম্পত্তি বর্ণনাকারীকে আলাদা করে তোলে ( writableএবং পরিবর্তে configurableসেট trueকরা উচিত false), যা পরবর্তী সময়ে ব্যতিক্রম ঘটায়।

  • এটি push()একাধিকবার আর্গুমেন্ট (যেমন myArray.push("a", "b")) দিয়ে একবার ডাকা হয় যখন ঘটনাটি একাধিকবার উত্থাপিত করে , যা আমার ক্ষেত্রে অপ্রয়োজনীয় এবং অভিনয় জন্য খারাপ ছিল।

সুতরাং এটি আমি সেরা সমাধানটি খুঁজে পেতে পারি যা পূর্ববর্তী সমস্যাগুলিকে সংশোধন করে এবং আমার মতে পরিষ্কার / সরল / বুঝতে সহজ।

Object.defineProperty(myArray, "push", {
    configurable: true,
    enumerable: false,
    writable: true, // Previous values based on Object.getOwnPropertyDescriptor(Array.prototype, "push")
    value: function (...args)
    {
        let result = Array.prototype.push.apply(this, args); // Original push() implementation based on https://github.com/vuejs/vue/blob/f2b476d4f4f685d84b4957e6c805740597945cde/src/core/observer/array.js and https://github.com/vuejs/vue/blob/daed1e73557d57df244ad8d46c9afff7208c9a2d/src/core/util/lang.js

        RaiseMyEvent();

        return result; // Original push() implementation
    }
});

আমার উত্সগুলির জন্য এবং কীভাবে পুশ ছাড়াও অন্যান্য পরিবর্তনকারী ফাংশনগুলি প্রয়োগ করতে হবে তার ইঙ্গিতগুলির জন্য দয়া করে মন্তব্যগুলি দেখুন: 'পপ', 'শিফট', 'আনশিফ্ট', 'স্প্লাইস', 'সাজান', 'বিপরীত'।


@ ক্যানন আমার কাছে প্রক্সি রয়েছে তবে আমি সেগুলি ব্যবহার করতে পারছি না কারণ অ্যারেটি বাহ্যিকভাবে পরিবর্তিত হয়েছে এবং আমি বাহ্যিক কলারদের (যা আমার নিয়ন্ত্রণ ছাড়াই সময়ে সময়ে পরিবর্তনের পাশাপাশি) প্রক্সি ব্যবহার করার জন্য জোর করার কোনও উপায় সম্পর্কে ভাবতে পারি না can't ।
cprcrack

@ ক্যানন এবং যাইহোক, আপনার মন্তব্য আমাকে ভুল ধারণা তৈরি করেছে, যা আমি স্প্রেড অপারেটরটি ব্যবহার করছি, যখন আসলে আমি নই। সুতরাং না, আমি মোটেই স্প্রেড অপারেটরকে লাভবান করছি না। আমি যা ব্যবহার করছি তা হল বাকী প্যারামিটার যা একই রকম ...সিনট্যাক্স রয়েছে এবং যা argumentsকীওয়ার্ডের ব্যবহারের সাহায্যে সহজেই প্রতিস্থাপন করা যেতে পারে ।
cprcrack


0
if (!Array.prototype.forEach)
{
    Object.defineProperty(Array.prototype, 'forEach',
    {
        enumerable: false,
        value: function(callback)
        {
            for(var index = 0; index != this.length; index++) { callback(this[index], index, this); }
        }
    });
}

if(Object.observe)
{
    Object.defineProperty(Array.prototype, 'Observe',
    {
        set: function(callback)
        {
            Object.observe(this, function(changes)
            {
                changes.forEach(function(change)
                {
                    if(change.type == 'update') { callback(); }
                });
            });
        }
    });
}
else
{
    Object.defineProperties(Array.prototype,
    { 
        onchange: { enumerable: false, writable: true, value: function() { } },
        Observe:
        {
            set: function(callback)
            {
                Object.defineProperty(this, 'onchange', { enumerable: false, writable: true, value: callback }); 
            }
        }
    });

    var names = ['push', 'pop', 'reverse', 'shift', 'unshift'];
    names.forEach(function(name)
    {
        if(!(name in Array.prototype)) { return; }
        var pointer = Array.prototype[name];
        Array.prototype[name] = function()
        {
            pointer.apply(this, arguments); 
            this.onchange();
        }
    });
}

var a = [1, 2, 3];
a.Observe = function() { console.log("Array changed!"); };
a.push(8);

4
দেখে মনে হচ্ছে Object.observe()এবং Array.observe()চশমা থেকে প্রত্যাহার করা হয়েছে। ইতিমধ্যে ক্রোম থেকে সমর্থন টানা হয়েছে। : /
ক্যানন

0

এটি একেবারে সমস্ত কিছু কভার করে কিনা তা নিশ্চিত নন তবে অ্যারেতে কোনও উপাদান যুক্ত রয়েছে তা সনাক্ত করতে আমি এই জাতীয় কিছু (বিশেষত ডিবাগিংয়ের সময়) ব্যবহার করি:

var array = [1,2,3,4];
array = new Proxy(array, {
    set: function(target, key, value) {
        if (Number.isInteger(Number(key)) || key === 'length') {
            debugger; //or other code
        }
        target[key] = value;
        return true;
    }
});

-1

একটি আকর্ষণীয় সংগ্রহ গ্রন্থাগারটি https://github.com/mgesmundo/smart-colલેક્શન । আপনাকে অ্যারে দেখতে এবং সেগুলিতেও ভিউ যুক্ত করতে দেয়। আমি নিজেই এটি পরীক্ষা করে নিচ্ছি বলে পারফরম্যান্স সম্পর্কে নিশ্চিত নই। শীঘ্রই এই পোস্ট আপডেট করা হবে।


-1

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

পারফরম্যান্স অনুযায়ী ... প্লে অ্যারে অবজেক্টের তুলনায় ওআরারি প্রায় 10-25 গুণ কম ধীর। 1 - 100 ব্যাপ্তির ক্যাপাসিটির জন্য পার্থক্যটি 1x-3x।

class OArray {
    constructor(capacity, observer) {

        var Obj = {};
        var Ref = []; // reference object to hold values and apply array methods

        if (!observer) observer = function noop() {};

        var propertyDescriptors = Object.getOwnPropertyDescriptors(Array.prototype);

        Object.keys(propertyDescriptors).forEach(function(property) {
            // the property will be binded to Obj, but applied on Ref!

            var descriptor = propertyDescriptors[property];
            var attributes = {
                configurable: descriptor.configurable,
                enumerable: descriptor.enumerable,
                writable: descriptor.writable,
                value: function() {
                    observer.call({});
                    return descriptor.value.apply(Ref, arguments);
                }
            };
            // exception to length
            if (property === 'length') {
                delete attributes.value;
                delete attributes.writable;
                attributes.get = function() {
                    return Ref.length
                };
                attributes.set = function(length) {
                    Ref.length = length;
                };
            }

            Object.defineProperty(Obj, property, attributes);
        });

        var indexerProperties = {};
        for (var k = 0; k < capacity; k++) {

            indexerProperties[k] = {
                configurable: true,
                get: (function() {
                    var _i = k;
                    return function() {
                        return Ref[_i];
                    }
                })(),
                set: (function() {
                    var _i = k;
                    return function(value) {
                        Ref[_i] = value;
                        observer.call({});
                        return true;
                    }
                })()
            };
        }
        Object.defineProperties(Obj, indexerProperties);

        return Obj;
    }
}

এটি বিদ্যমান উপাদানগুলিতে কাজ করার সময়, অ্যারের [new_index] = মান সহ কোনও উপাদান যুক্ত করা হলে এটি কাজ করে না। কেবল প্রক্সিরা তা করতে পারে।
এমএমএম

-5

আমি আপনাকে দেশীয় প্রোটোটাইপগুলি বাড়ানোর পরামর্শ দেব না। পরিবর্তে, আপনি নতুন-তালিকার মতো একটি লাইব্রেরি ব্যবহার করতে পারেন; https://github.com/azer/new-list

এটি একটি নেটিভ জাভাস্ক্রিপ্ট অ্যারে তৈরি করে এবং আপনাকে যে কোনও পরিবর্তনের জন্য সাবস্ক্রাইব করতে দেয়। এটি আপডেটগুলি ব্যাচ করে এবং আপনাকে চূড়ান্ত পার্থক্য দেয়;

List = require('new-list')
todo = List('Buy milk', 'Take shower')

todo.pop()
todo.push('Cook Dinner')
todo.splice(0, 1, 'Buy Milk And Bread')

todo.subscribe(function(update){ // or todo.subscribe.once

  update.add
  // => { 0: 'Buy Milk And Bread', 1: 'Cook Dinner' }

  update.remove
  // => [0, 1]

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