JQuery এর প্রসারিত পদ্ধতির সমান জাভাস্ক্রিপ্ট


94

পটভূমি

আমার একটি ফাংশন রয়েছে যা কোনও configবস্তুকে আর্গুমেন্ট হিসাবে গ্রহণ করে । ফাংশনের মধ্যে আমারও defaultআপত্তি আছে। এই প্রতিটি বস্তুর মধ্যে এমন বৈশিষ্ট্য রয়েছে যা ফাংশনটির মধ্যে কোডের বাকি অংশের জন্য সেটিংস হিসাবে মূলত কাজ করে। configঅবজেক্টের মধ্যে সমস্ত সেটিংস নির্দিষ্ট করে দেওয়া রোধ করার জন্য , আমি জিকুয়েরির extendপদ্ধতিটি একটি নতুন অবজেক্ট পূরণ করতে ব্যবহার করি , বস্তুটিতে settingsকোনও ডিফল্ট মান defaultযদি সেগুলিতে নির্দিষ্ট না করা থাকে config:

var config = {key1: value1};
var default = {key1: default1, key2: default2, key 3: default 3};

var settings = $.extend(default, config);

//resulting properties of settings:
settings = {key1: value1, key2: default2, key 3: default 3};

সমস্যা

এটি দুর্দান্ত কাজ করে তবে আমি jQuery এর প্রয়োজন ছাড়াই এই কার্যকারিতাটি পুনরুত্পাদন করতে চাই। প্লেইন ওল জাভাস্ক্রিপ্ট দিয়ে এটি করার জন্য কি সমান মার্জিত (বা কাছাকাছি) অর্থ আছে?


সম্পাদনা করুন: নন-সদৃশ জাস্টিফিকেশন

এই প্রশ্নটি " আমি কীভাবে দুটি জাভাস্ক্রিপ্ট অবজেক্টের সম্পত্তি গতিশীলভাবে মার্জ করতে পারি? " প্রশ্নের সদৃশ নয় । যেখানে এই প্রশ্নটি কেবল একটি পৃথক দুটি বস্তু থেকে সমস্ত কী এবং মানগুলিকে ধারণ করে এমন একটি বস্তু তৈরি করতে চায় - আমি বিশেষভাবে উভয় বস্তুতে কিছু কী ভাগ না করে সমস্ত কী ভাগ করে দেয় এবং কোন বস্তুটি প্রাধান্য পাবে এমন পরিস্থিতিতে কীভাবে এটি করতে হবে তা সম্বোধন করতে চাই ( ডিফল্ট) ইভেন্টটিতে ফলাফলটির জন্য সেখানে সদৃশ কী রয়েছে। এবং আরও সুনির্দিষ্টভাবে, আমি এটি অর্জনের জন্য jQuery এর পদ্ধতির ব্যবহারকে সম্বোধন করতে চেয়েছিলাম এবং jQuery ছাড়াই এটির বিকল্প উপায় খুঁজতে চাই। উভয় প্রশ্নের উত্তর অনেকগুলি ওভারল্যাপ করার সময়, এর অর্থ এই নয় যে প্রশ্নগুলি নিজেরাই একই are


8
শুধু পথ jQuery এর আছে এটা চুরি james.padolsey.com/jquery/#v=1.6.2&fn=jQuery.extend :-P
রকেট Hazmat

ভাল ধারণা @ রকেটহাজমাত, আপনি যদি সেই ফাংশনটি কপিপাস্ট করেন তবে নোট করুন এতে আরও কয়েকটি jQuery নির্ভরতা রয়েছে jQuery.isPlainObjectএবংjQuery.isFunction
অ্যান্ডি র‌্যাডট্যাজ

উত্তর:


133

আপনার কোডে ফলাফল পেতে, আপনি এটি করবেন:

function extend(a, b){
    for(var key in b)
        if(b.hasOwnProperty(key))
            a[key] = b[key];
    return a;
}

মনে রাখবেন যে আপনি সেখানে যেভাবে প্রসারিত করেছেন সেটি ডিফল্ট অবজেক্টটি সংশোধন করবে। যদি আপনি এটি না চান, ব্যবহার করুন

$.extend({}, default, config)

আরও শক্তিশালী সমাধান যা jQuery এর কার্যকারিতা নকল করে নীচে হবে:

function extend(){
    for(var i=1; i<arguments.length; i++)
        for(var key in arguments[i])
            if(arguments[i].hasOwnProperty(key))
                arguments[0][key] = arguments[i][key];
    return arguments[0];
}

4
আমি ক্রিয়াকলাপের একটি কোড উদাহরণ দেখতে চাই, সম্ভবত ফ্রিডল, কারণ প্লেইন জেএস অনেক বেশি শীতল তবে বিমূর্ত, ধন্যবাদ মিলিয়নকে।
thednp

4
এই পুনরাবৃত্তি হয় না, যেমন ex। সম্প্রসারিত করে
এক্কিস

30

আপনি অবজেক্ট.সেসাইন ব্যবহার করতে পারেন।

var defaults = {key1: "default1", key2: "default2", key3: "defaults3"};
var config = {key1: "value1"};

var settings = Object.assign({}, defaults, config); // values in config override values in defaults
console.log(settings); // Object {key1: "value1", key2: "default2", key3: "defaults3"}

এটি এক বা একাধিক উত্স অবজেক্ট থেকে একটি লক্ষ্য অবজেক্টে সমস্ত পরিগণিত নিজস্ব সম্পত্তিগুলির মানগুলি অনুলিপি করে এবং লক্ষ্য বস্তুকে প্রত্যাবর্তন করে।

Object.assign(target, ...sources)

এটি আইই বাদে সমস্ত ডেস্কটপ ব্রাউজারে কাজ করে (তবে এজ সহ)। এটি মোবাইল সমর্থন হ্রাস করেছে।

এখানে নিজের জন্য দেখুন: https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / গ্লোবাল_অবজেক্টস / অবজেক্ট / পাস

গভীর অনুলিপি সম্পর্কে

যাইহোক, অবজেক্ট.সেসিনে জিকিউরির প্রসারিত পদ্ধতির গভীর বিকল্প নেই।

দ্রষ্টব্য: আপনি সাধারণত অনুরূপ প্রভাবের জন্য JSON ব্যবহার করতে পারেন

var config = {key1: "value1"};
    var defaults = {key1: "default1", key2: "default2", keyDeep: {
        kd1: "default3",
        kd2: "default4"
    }};
    var settings = JSON.parse(JSON.stringify(Object.assign({}, defaults, config))); 
    console.log(settings.keyDeep); // Object {kd1: "default3", kd2: "default4"}

হ্যাঁ, তবে এখানে এটি ডিফল্ট থেকে কী 1 এর উপরে ঝাঁপিয়ে পড়ে এবং নতুন অবজেক্টে এটি যোগ করছে না।
আয়নুত নেখুলা

@ অজ্ঞাতনামা আসলে এটি এটিকে যুক্ত করে না তবে এটি কনফিগার অ্যারে থেকে কী 1 মান দ্বারা ওভাররাইড হয়ে যায়।
লিংক

আমার ধারণা ছিল যে ঘটছে। সুতরাং, এটি পুরোপুরি যোগ করা হচ্ছে না।
আয়নুত নেখুলা

29

আপনি ইসিএমএ 2018 স্প্রেড অপারেটরটিকে অবজেক্ট লিটারালগুলিতে ব্যবহার করতে পারেন ...

var config = {key1: value1};
var default = {key1: default1, key2: default2, key 3: default 3};

var settings = {...default, ...config}

//resulting properties of settings:
settings = {key1: value1, key2: default2, key 3: default 3};

পুরানো ব্রাউজারগুলির জন্য বাবেলজেএস সমর্থন


4
এটি করার সবচেয়ে সুন্দরতম এবং পরিষ্কার উপায়!
ভেলোজেট

4

এটি একটি জিকিউরি নির্ভরতা নির্মূল করার চেষ্টা করার সময় গভীর অনুলিপি সহ আমার সামান্য ভিন্ন পদ্ধতির। এটি বেশিরভাগই ছোট হওয়ার জন্য তৈরি করা হয়েছে যাতে এটির সমস্ত বৈশিষ্ট্য যেমনটি প্রত্যাশা করে না। সম্পূর্ণ ES5- সামঞ্জস্যপূর্ণ হওয়া উচিত ( আইজ 9.কিজ অবজেক্ট.কিসের ব্যবহারের কারণে )

function extend(obj1, obj2) {
    var keys = Object.keys(obj2);
    for (var i = 0; i < keys.length; i += 1) {
      var val = obj2[keys[i]];
      obj1[keys[i]] = ['string', 'number', 'array', 'boolean'].indexOf(typeof val) === -1 ? extend(obj1[keys[i]] || {}, val) : val;
    }
    return obj1;
  }

আপনি ভাবতে পারেন যে পঞ্চম লাইনটি হুবহু কী করে ... অবজেক্ট.কি যদি কোনও বস্তু আক্ষরিক হয় (যেমন এটি কোনও সাধারণ ধরণের না হয়) তবে আমরা এটির পুনরাবৃত্তভাবে প্রসারিতকে কল করি। যদি সেই নামে কোনও সম্পত্তি এখনও অজাব 1 এ উপস্থিত না থেকে থাকে তবে আমরা প্রথমে এটি একটি খালি বস্তুতে শুরু করি। অন্যথায় আমরা কেবল obj1.key সেট করতে ob2.key।

এখানে আমার মোচা / চই টেস্টগুলির কয়েকটি রয়েছে যা সাধারণ কেসগুলি এখানে কাজ করার জন্য প্রমাণ করা উচিত:

it('should extend a given flat object with another flat object', () => {
  const obj1 = {
    prop1: 'val1',
    prop2: 42,
    prop3: true,
    prop4: 20.16,
  };
  const obj2 = {
    prop4: 77.123,
    propNew1: 'newVal1',
    propNew2: 71,
  };
  assert.deepEqual(utils.extend(obj1, obj2), {
    prop1: 'val1',
    prop2: 42,
    prop3: true,
    prop4: 77.123,
    propNew1: 'newVal1',
    propNew2: 71,
  });
});

it('should deep-extend a given flat object with a nested object', () => {
  const obj1 = {
    prop1: 'val1',
    prop2: 'val2',
  };
  const obj2 = {
    propNew1: 'newVal1',
    propNew2: {
      propNewDeep1: 'newDeepVal1',
      propNewDeep2: 42,
      propNewDeep3: true,
      propNewDeep4: 20.16,
    },
  };
  assert.deepEqual(utils.extend(obj1, obj2), {
    prop1: 'val1',
    prop2: 'val2',
    propNew1: 'newVal1',
    propNew2: {
      propNewDeep1: 'newDeepVal1',
      propNewDeep2: 42,
      propNewDeep3: true,
      propNewDeep4: 20.16,
    },
  });
});

it('should deep-extend a given nested object with another nested object and deep-overwrite members', () => {
  const obj1 = {
    prop1: 'val1',
    prop2: {
      propDeep1: 'deepVal1',
      propDeep2: 42,
      propDeep3: true,
      propDeep4: {
        propDeeper1: 'deeperVal1',
        propDeeper2: 777,
        propDeeper3: 'I will survive',
      },
    },
    prop3: 'lone survivor',
  };
  const obj2 = {
    prop1: 'newVal1',
    prop2: {
      propDeep1: 'newDeepVal1',
      propDeep2: 84,
      propDeep3: false,
      propDeep4: {
        propDeeper1: 'newDeeperVal1',
        propDeeper2: 888,
      },
    },
  };
  assert.deepEqual(utils.extend(obj1, obj2), {
    prop1: 'newVal1',
    prop2: {
      propDeep1: 'newDeepVal1',
      propDeep2: 84,
      propDeep3: false,
      propDeep4: {
        propDeeper1: 'newDeeperVal1',
        propDeeper2: 888,
        propDeeper3: 'I will survive',
      },
    },
    prop3: 'lone survivor',
  });
});

আমি এই বাস্তবায়ন সম্পর্কে প্রতিক্রিয়া বা মন্তব্য সম্পর্কে খুশি হতে হবে। আগাম ধন্যবাদ!


2

আপনি forস্টেটমেন্ট ব্যবহার করে অবজেক্টের বৈশিষ্ট্যগুলি লুপ করতে পারেন ।

var settings = extend(default, config);

function extend(a, b){
    var c = {};
    for(var p in a)
        c[p] = (b[p] == null) ? a[p] : b[p];
    return c;
}

4
এটি যে বৈশিষ্ট্যগুলিতে বিদ্যমান নেই সেগুলি গ্রহণ করবে না a। যদিও এটি উদাহরণস্বরূপ নয়, $.extendপ্রকৃতপক্ষে সেভাবে কাজ করে, সমস্ত বস্তুর সমস্ত বৈশিষ্ট্য মার্জ করে।
ফেলিক্স ক্লিং

4
আমি jquery বেস কোডটি পড়ার সাথে সাথে এটি মানটি অনুলিপি করতে বা ক্লোন করতে আসলে একটি পুনরাবৃত্ত ফাংশন করে। সুতরাং এটি গভীরভাবে ক্লোন / অনুলিপি করা, কেবল উপরের কোড হিসাবে প্রথম স্তরে অনুলিপি করা নয়।
আলাদাইন

2

আমি এই কোডটি পছন্দ করি যা আমার প্রতিটি জেনেরিক ব্যবহার করে, এবং প্রথম বস্তুকে ম্যাঙ্গাল করে না:

function forEachIn(obj, fn) {
    var index = 0;
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            fn(obj[key], key, index++);
        }
    }
}

function extend() {
    var result = {};
    for (var i = 0; i < arguments.length; i++) {
        forEachIn(arguments[i],
            function(obj, key) {
                result[key] = obj;
            });
    }
    return result;
}

আপনি যদি সত্যই প্রথম বস্তুর সাথে জিনিসগুলি মার্জ করতে চান তবে আপনি এটি করতে পারেন:

obj1 = extend(obj1, obj2);

এটি এখানকার সেরা উত্তর। এটি গভীর অনুলিপি করে, প্রথম বস্তুকে ম্যাঙ্গেল করে না, অসীম বস্তুগুলিকে সমর্থন করে এবং প্রসারিত করার সময় বিভিন্ন ধরণের পরিবর্তন করতে পারে (অর্থাত এখানে অনেক উত্তর একটি বস্তুর কাছে স্ট্রিং প্রসারিত করবে না, এই উত্তরটি দেবে)। এটি আমার বইয়ের প্রতিটি চেক চিহ্ন পেয়েছে। সম্পূর্ণ প্রসারিত প্রতিস্থাপন, এবং বোঝার জন্য অত্যন্ত সহজ।
নিক স্টিল

0

আমি খাঁটি জাভাস্ক্রিপ্ট নিয়ে বিকাশ করলে এটি আমাকে অনেক সাহায্য করে।

function extends(defaults, selfConfig){
     selfConfig = JSON.parse(JSON.stringify(defaults));
     for (var item in config) {
         if (config.hasOwnProperty(item)) {
             selfConfig[item] = config[item];
         }
     }
     return selfConfig;
}

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