কেন MyObj.hasOwnProperty (প্রোপ) এর পরিবর্তে অবজেক্ট.প্রোটোটাইপ.হস ওউনপ্রোপার্টি.call (মাইওবিজে, প্রোপ) ব্যবহার করবেন?


107

আমি যদি সঠিকভাবে বুঝতে পারি তবে জাভাস্ক্রিপ্টের প্রতিটি বস্তু অবজেক্ট প্রোটোটাইপ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত, যার অর্থ জাভাস্ক্রিপ্টের প্রতিটি বস্তুটির প্রোটোটাইপ চেইনের মাধ্যমে hasOwnProperty ফাংশনে অ্যাক্সেস রয়েছে।

প্রয়োজনীয় জেএস'র উত্স কোডটি পড়ার সময় আমি এই ফাংশনটিতে হোঁচট খেয়েছি :

function hasProp(obj, prop) {
    return hasOwn.call(obj, prop);
}

hasOwnএকটি রেফারেন্স Object.prototype.hasOwnProperty। এই ফাংশন হিসাবে লিখতে কোন ব্যবহারিক পার্থক্য আছে কি

function hasProp(obj, prop) {
    return obj.hasOwnProperty(prop);
}

এবং যেহেতু আমরা এটিতে রয়েছি, কেন আমরা এই ফাংশনটি মোটেই সংজ্ঞায়িত করব? এটি কি শর্টকাট এবং (সামান্য) পারফরম্যান্স লাভের জন্য সম্পত্তি অ্যাক্সেসের স্থানীয় ক্যাচিংয়ের প্রশ্ন, বা আমি যে কোনও ক্ষেত্রে মিস করছি যেখানে এই পদ্ধতিটি নেই এমন বস্তুগুলিতে হ্যাঁসনপ্রপার্টি ব্যবহার করা যেতে পারে?

উত্তর:


113

[আমার উদাহরণগুলির মধ্যে] কি কোনও ব্যবহারিক পার্থক্য রয়েছে?

ব্যবহারকারীর সাথে একটি জাভাস্ক্রিপ্ট অবজেক্ট তৈরি করা থাকতে পারে Object.create(null), যার একটি null [[Prototype]]শৃঙ্খল থাকবে, এবং তাই hasOwnProperty()এটিতে উপলব্ধ হবে না । আপনার দ্বিতীয় ফর্মটি ব্যবহার করে এই কারণে কাজ করতে ব্যর্থ হবে।

এটি একটি নিরাপদ উল্লেখ Object.prototype.hasOwnProperty()(এবং আরও ছোট))

আপনি কল্পনা করতে পারেন যে কেউ এটি করেছে ...

var someObject = {
    hasOwnProperty: function(lol) {
        return true;
    }
};

কোনটি হবে hasProp(someObject)এটা আপনার দ্বিতীয় উদাহরণটি বাস্তবায়িত হয়েছে Fail (এটা যে পদ্ধতি সরাসরি বস্তুর উপর এবং যে ডাকে, এটি হবে পরিবর্তে অর্পণ হচ্ছে Object.prototype.hasOwnProperty)।

তবে সম্ভবত কেউ Object.prototype.hasOwnPropertyরেফারেন্সটিকে ওভাররাইড করেছে ।

এবং যেহেতু আমরা এটিতে রয়েছি, কেন আমরা এই ফাংশনটি মোটেই সংজ্ঞায়িত করব?

উপরে দেখুন.

এটি কি শর্টকাট এবং (সামান্য) পারফরম্যান্স লাভের জন্য সম্পত্তি অ্যাক্সেসের স্থানীয় ক্যাশিংয়ের প্রশ্ন ...

এটা করতে পারে দ্রুততর তত্ত্ব, যেমন [[Prototype]]চেইন অনুসরণ করা হবে তা নয়, কিন্তু আমি এই তুচ্ছ হতে সন্দেহ এবং না কারণ বাস্তবায়ন কেন এটা।

... বা আমি এমন কোনও ক্ষেত্রে মিস করছি যেখানে hasOwnPropertyএই পদ্ধতিতে নেই এমন কোনও জিনিস ব্যবহার করা যেতে পারে?

hasOwnProperty()চালু আছে Object.prototype, তবে ওভাররাইড করা যায়। প্রতিটি নেটিভ জাভাস্ক্রিপ্ট অবজেক্ট (তবে হোস্ট অবজেক্টগুলি এটি অনুসরণ করার গ্যারান্টিযুক্ত নয়, রবজির গভীরতার ব্যাখ্যা দেখুন ) এর Object.prototypeআগে শৃঙ্খলে তার শেষ অবজেক্ট হিসাবে রয়েছে null(অবশ্যই প্রত্যাবর্তিত বস্তুর জন্য বাদে Object.create(null))।


আপনার যুক্তি সম্ভবত সঠিক, তবে আমি মনে করি আপনি সদয় হন। যদি প্রয়োজনীয়.js এর লেখকরা মনে করেন যে ওজনপ্র্টিটি ওভাররাইড করা হয়ে থাকতে পারে (যা চূড়ান্ত সম্ভাবনা নেই), তবে তাদের সমস্ত বিল্ট-ইন পদ্ধতিগুলি সেইভাবে কল করা উচিত (সম্ভবত তারা করেন)।
রবজি

@ পেরিব্যাক সত্যই? আমি নিশ্চিত যে এটি এটি সমর্থন করেছে।
অ্যালেক্স

ES6 শর্টকাট যদি প্রায়শই ব্যবহৃত হয়। const hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
রিচার্ড অয়েট

15

আমি যদি সঠিকভাবে বুঝতে পারি তবে জাভাস্ক্রিপ্টের প্রতিটি এবং অবজেক্ট প্রোটোটাইপ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত

এটি বিভক্ত চুলের মতো মনে হতে পারে তবে জাভাস্ক্রিপ্টের (ইসকামস্ক্রিপ্ট প্রয়োগের জেনেরিক শব্দ) এবং এর মধ্যে পার্থক্য রয়েছে ECMAScript (জাভাস্ক্রিপ্ট প্রয়োগের জন্য ব্যবহৃত ভাষা । এটি ECMAScript যা জাভাস্ক্রিপ্ট নয়, একটি উত্তরাধিকারের স্কিমকে সংজ্ঞায়িত করে, সুতরাং কেবল দেশীয় ECMAScript অবজেক্টগুলিকে সেই উত্তরাধিকার প্রকল্পটি বাস্তবায়ন করতে হবে।

একটি চলমান জাভাস্ক্রিপ্ট প্রোগ্রাম অন্তত অন্তর্নির্মিত E ECMAScript অবজেক্ট (অবজেক্ট, ফাংশন, সংখ্যা, ইত্যাদি) এবং সম্ভবত কিছু নেটিভ অবজেক্ট (যেমন ফাংশন) নিয়ে গঠিত consists এটিতে কিছু হোস্ট অবজেক্ট (যেমন ব্রাউজারে DOM অবজেক্টস, বা অন্যান্য হোস্ট এনভায়রনমেন্টের অন্যান্য অবজেক্ট) থাকতে পারে।

বিল্ট-ইন এবং নেটিভ অবজেক্টস অবশ্যই অবশ্যই ইসিএমএ-262 এ সংজ্ঞায়িত উত্তরাধিকার স্কিমটি বাস্তবায়ন করবে, হোস্ট বস্তুগুলি তা করে না। অতএব, একটি জাভাস্ক্রিপ্ট পরিবেশে সমস্ত বস্তুর অবশ্যই অবজেক্ট.প্রোটোটাইপ থেকে উত্তরাধিকারী হতে হবে না । উদাহরণস্বরূপ, Internet Explorer এ হোস্ট বস্তু বাস্তবায়িত যেমন জন্য ActiveX যদি নেটিভ বস্তু (অত: পর কেন হিসাবে গণ্য বস্তু ত্রুটি নিক্ষেপ করা হবে try..catch মাইক্রোসফট ইনিশিয়ালাইজ করতে ব্যবহৃত হয় XMLHttpRequest- এর বস্তু)। কিছু ডিওএম অবজেক্টস (যেমন কুইর্কস মোডে ইন্টারনেট এক্সপ্লোরারে নোডলিস্টস) যদি অ্যারে পদ্ধতিতে পাস করা হয় তবে ত্রুটি ছুঁড়ে ফেলা হবে, ইন্টারনেট এক্সপ্লোরার 8 এবং নিম্নের ডিওএম অবজেক্টগুলির নেই ইসিএমএস স্ক্রিপ্ট inherit যেমন উত্তরাধিকার প্রকল্পের মতো নয়, ইত্যাদি।

সুতরাং এটি ধরে নেওয়া উচিত নয় যে একটি জাভাস্ক্রিপ্ট পরিবেশে সমস্ত বস্তু অবজেক্ট.প্রোটোটাইপ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত।

যার অর্থ জাভাস্ক্রিপ্টের প্রতিটি বস্তুর প্রোটোটাইপ চেইনের মাধ্যমে haswwPPererty ফাংশনে অ্যাক্সেস রয়েছে

কমপক্ষে ইন্টারনেট এক্সপ্লোরারে নির্দিষ্ট হোস্ট অবজেক্টের জন্য সত্য নয় (এবং ইন্টারনেট এক্সপ্লোরার 8 এবং সর্বদা কম)।

উপরের দিক থেকে, কেন চিন্তা করা মূল্যবান যে কোনও জিনিসের নিজস্ব নিজস্ব ওজনপ্রোপার্টি পদ্ধতি থাকতে পারে এবং যদি এটি কোনও ভাল ধারণা হয় বা না হয় তবে প্রথমে পরীক্ষা না করেই কিছু অন্য has'wnProperty পদ্ধতি কল করার পরামর্শ দেওয়া উচিত ।

আমি সন্দেহ করি যে ব্যবহার করার কারণটি Object.prototype.hasOwnProperty.callহ'ল কিছু ব্রাউজারে, হোস্ট অবজেক্টের কল ব্যবহার করে একটি হ'ল ওপেনপ্র্টি পদ্ধতি নেই don't এবং বিল্ট বিকল্প is যাইহোক, সাধারণভাবে এটি করা উপরে উল্লিখিত কারণগুলির জন্য ভাল ধারণা বলে মনে হচ্ছে না।

কোথায় হোস্ট বস্তু উদ্বিগ্ন, অপারেটর বৈশিষ্ট্যের জন্য পরীক্ষা সাধারণত ব্যবহার করা যেতে পারে, যেমন

var o = document.getElementsByTagName('foo');

// false in most browsers, throws an error in Internet Explorer 6, and probably 7 and 8
o.hasOwnProperty('bar');

// false in all browsers
('bar' in o);

// false (in all browsers? Do some throw errors?)
Object.prototype.hasOwnProperty.call(o, 'bar');

একটি বিকল্প ( ইন্টারনেট এক্সপ্লোরার 6 এবং অন্যান্যতে পরীক্ষিত ):

function ownProp(o, prop) {

  if ('hasOwnProperty' in o) {
    return o.hasOwnProperty(prop);

  } else {
    return Object.prototype.hasOwnProperty.call(o, prop);
  }
}

এইভাবে আপনি কেবলমাত্র বিল্ট-কে হ্যাঁসনপ্রপার্টিটিতে কল করবেন যেখানে বস্তুর এটি নেই (উত্তরাধিকারসূত্রে বা অন্যথায়)।

যাইহোক, যদি একটি বস্তু একটি নেই hasOwnPropertyপদ্ধতি, এটা সম্ভবত ঠিক যেমন উপযুক্ত ব্যবহার করবেন তা যেমন বস্তুর সম্ভবত একটি উত্তরাধিকার পরিকল্পনা নেই এবং সব সম্পত্তি বস্তুর উপর হয় (শুধু একটি ধৃষ্টতা যদিও যে) অপারেটর, যেমন মধ্যে অপারেটর একটি সাধারণ (এবং আপাতদৃষ্টিতে সফল) বৈশিষ্ট্যের জন্য করে DOM অবজেক্ট সমর্থনের জন্য পরীক্ষার উপায়।


ধন্যবাদ অবজেক্ট.প্রোটোটাইপ.হস ওনপ্রোপার্টি.ক্যাল (ও, 'বার') এফএফ 18.0 এ কাজ করছে না (কমপক্ষে আমার ক্ষেত্রে)। তাই আমি সিদ্ধান্ত নিয়েছি (ও তে 'বার') - এবং এটি সাহায্য করেছিল।
সর্বোচ্চ

@ ম্যাক্স inএকটি hasOwnProperty()অনুসন্ধান সম্পাদন করে না , আমি সন্দেহ করি যে প্রোটোটাইপ শৃঙ্খলে আপনি যে সম্পত্তিটি খুঁজছিলেন তা বিদ্যমান।
অ্যালেক্স

এটি eslint.org/docs/rules/no-prototype-builtins- এর একটি আকর্ষণীয় উদাহরণ : উদাহরণস্বরূপ, কোনও ওয়েবসার্ভার কোনও ক্লায়েন্টের থেকে JSON ইনপুট পার্স hasOwnPropertyকরা এবং ফলস্বরূপ অবজেক্টটিতে সরাসরি কল করা নিরাপদ হবে , কারণ দূষিত ক্লায়েন্ট পারে একটি JSON মান প্রেরণ করুন {"hasOwnProperty": 1}এবং সার্ভারকে ক্রাশ করার কারণ দিন।
নট 101

অবশ্যই, তবে যে কোনও ক্লায়েন্টকে পরীক্ষা বা বৈধতা দেওয়া বুদ্ধিমানের কাজ হবে such এই জাতীয় সমস্যাগুলি প্রতিরোধের জন্য জেএসওএন সরবরাহকৃত জেএসওএনকে সরবরাহ করা, যদিও আপনার উদ্বেগ কেবলমাত্র ডেটা মানের ছিল। এবং এটি সার্ভারকে ক্রাশ করার কারণ নয়। :-)
রবজি

8

জাভাস্ক্রিপ্টটি সম্পত্তি নামের মালিকানা রক্ষা করে না rop

যদি এই সম্ভাবনাটি বিদ্যমান থাকে যে কোনও নামের এই নাম সহ কোনও সম্পত্তি থাকতে পারে, সঠিক ফলাফল পেতে এটি একটি বাহ্যিক হ্যাসঅনপ্রোপার্টি ব্যবহার করা প্রয়োজন:

আরও ভাল বোঝার জন্য আপনি নীচের কোড স্নিপেটগুলি আপনার ব্রাউজার কনসোলে পেস্ট করতে পারেন

var foo = {
  hasOwnProperty: function() {
    return false;
  },
  bar: 'I belong to foo'
};

সর্বদা মিথ্যা প্রত্যাবর্তন

foo.hasOwnProperty('bar'); // false

অন্য একটি অবজেক্টের হ'ল ওয়ানপ্রোপার্টি ব্যবহার করুন এবং এই সেটটি দিয়ে ফু-এ কল করুন

({}).hasOwnProperty.call(foo, 'bar'); // true

এই উদ্দেশ্যটির জন্য অবজেক্ট প্রোটোটাইপ থেকে হ্যাশঅনপ্রপার্টি সম্পত্তি ব্যবহার করাও সম্ভব

Object.prototype.hasOwnProperty.call(foo, 'bar'); // true

4
বিন্দু আপনি তৈরি করছেন ইতিমধ্যে করা হয়েছে গৃহীত উত্তর বলে কিছু নেই ওভাররাইড ছাড়া, hasOwnPropertyআয় true
লুই

1

প্রথম দুটি উত্তর (তারিখ দ্বারা) উভয় দেওয়া তথ্য স্পট হয়। তবে, এর ব্যবহার:

('propertyName' in obj)

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

inঅপারেটর খুব প্রোটোটাইপ চেইন মাধ্যমে নিচে পরিদর্শন করবে।

এর অর্থ এই যে hasOwnPropertyপ্রোটোটাইপ বৈশিষ্ট্যগুলি মিথ্যা হিসাবে প্রত্যাবর্তিত হবে সেখানে স্থানান্তরিত হলে উদাহরণ বৈশিষ্ট্যগুলি সত্য হবে।

inঅপারেটর উভয় উদাহরণ এবং প্রোটোটাইপ বৈশিষ্ট্য ব্যবহার করে সত্য ফিরে আসবে।

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