কোনও অবজেক্টের অ-গণ্য উত্তরাধিকার সূত্রে প্রাপ্ত সম্পত্তি নাম পাওয়া কি সম্ভব?


103

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

1) Object.keys(), যা কোনও সামগ্রীর সমস্ত, নিজস্ব গুণগত গুণাবলী, একটি ইসিএমএ 5 পদ্ধতি প্রদান করে।

২) একটি for...inলুপ, যা কোনও সামগ্রীর সমস্ত গুণমানের বৈশিষ্ট্য ফিরিয়ে দেয়, সেগুলি তার নিজস্ব সম্পত্তি হ'ল বা প্রোটোটাইপ শৃঙ্খল থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হোক।

3) Object.getOwnPropertyNames(obj)যা একটি বস্তুর সমস্ত নিজস্ব সম্পত্তি প্রদান করে, গণনাযোগ্য বা না।

আমাদের কাছে এমন পদ্ধতি রয়েছে যেমন hasOwnProperty(prop)আমাদের কোনও সম্পত্তি উত্তরাধিকার সূত্রে প্রাপ্ত কিনা বা বাস্তবে সেই অবজেক্টের অন্তর্ভুক্ত propertyIsEnumerable(prop)কিনা তা যাচাই করতে দেয় এবং নাম অনুসারে যেটি সম্পত্তি হিসাবে অগণনীয় তা পরীক্ষা করতে দেয়।

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

ধন্যবাদ.


4
আপনার প্রশ্নের উত্তরে আমি যে প্রশ্নটি করতে যাচ্ছিলাম তার উত্তর দিয়েছি: অ-গণনাযোগ্য বৈশিষ্ট্যগুলি কীভাবে পরীক্ষা করবেন (কেবলমাত্র পূর্বনির্ধারিত বস্তুগুলিতে কী আছে তা সন্ধান করতে)। অবশেষে আমি getOwNPropertyNames পেয়েছি! :-)
মার্কাস

4
@ মার্কাস :-) এটাই তাই!
dkugappi

উত্তর:


115

যেহেতু getOwnPropertyNamesআপনাকে অগণিত গুণাবলী পাওয়া যায় তাই আপনি এটি ব্যবহার করতে এবং প্রোটোটাইপ চেইন আপ করার সাথে এটি একত্রিত করতে পারেন।

function getAllProperties(obj){
    var allProps = []
      , curr = obj
    do{
        var props = Object.getOwnPropertyNames(curr)
        props.forEach(function(prop){
            if (allProps.indexOf(prop) === -1)
                allProps.push(prop)
        })
    }while(curr = Object.getPrototypeOf(curr))
    return allProps
}

আমি সাফারি 5.1 এ এটি পরীক্ষা করেছি এবং পেয়েছি

> getAllProperties([1,2,3])
["0", "1", "2", "length", "constructor", "push", "slice", "indexOf", "sort", "splice", "concat", "pop", "unshift", "shift", "join", "toString", "forEach", "reduceRight", "toLocaleString", "some", "map", "lastIndexOf", "reduce", "filter", "reverse", "every", "hasOwnProperty", "isPrototypeOf", "valueOf", "__defineGetter__", "__defineSetter__", "__lookupGetter__", "propertyIsEnumerable", "__lookupSetter__"]

আপডেট: কোডটি কিছুটা রিফ্যাক্টড (যুক্ত স্পেস এবং কোঁকড়া ধনুর্বন্ধনী, এবং ফাংশনের নাম উন্নত):

function getAllPropertyNames( obj ) {
    var props = [];

    do {
        Object.getOwnPropertyNames( obj ).forEach(function ( prop ) {
            if ( props.indexOf( prop ) === -1 ) {
                props.push( prop );
            }
        });
    } while ( obj = Object.getPrototypeOf( obj ) );

    return props;
}

4
ধন্যবাদ টুবাইয়ের মাধ্যমে, একটি জিনিস যা আমি বুঝতে পারি না তা হ'ল লাইন: while(curr = Object.getPrototypeOf(cure))যেমন শর্তসাপেক্ষ বিবৃতিটি তুলনামূলক অপারেটরের পরিবর্তে একটি অ্যাসাইনমেন্ট অপারেটর ব্যবহার করে, এটি কি সবসময় সত্য হয় না? অথবা এই লাইনটি মূলত "কারার" এর প্রোটোটাইপ আছে কিনা তা যাচাই করছে?
dkugappi

4
@ অ্যালেক্সনাবোকভ এই ফল মিথ্যা বললে মিথ্যা প্রত্যাবর্তন করবে, যা প্রোটোটাইপ শৃঙ্খলের শীর্ষে Object.getPrototypeOf(cure)ফিরে nullআসার পরে ঘটবে । আমি অনুমান করি এটি কোনও বিজ্ঞপ্তি প্রোটোটাইপ চেইন ধরে নেই!
ডোমেনিক

4
Function.prototypeপ্রোটোটাইপ লিঙ্কটি নির্দেশ করে যেহেতু অ্যালেক্স কখনই "মূল" প্রোটোটাইপ হতে পারে না Object.prototype। ফাংশনটি Object.getPrototypeOf( obj )প্রোটোটাইপ চেইনের শীর্ষতম বস্তুটি প্রদান করে obj। এটি আপনাকে প্রোটোটাইপ চেইন অনুসরণ করতে সক্ষম করে objযতক্ষণ না আপনি তার শেষ ( nullমান) পৌঁছায় । আমি নিশ্চিত নই যে এটি নিয়ে আপনার সমস্যাটি কী ...
Šime Vidas

4
@ অ্যালেক্স না, তা না undefined। বস্তুটি Object.getPrototypeOf(John)ফেরত দেয় Boy.prototype(যেমনটি করা উচিত) - এখানে দেখুন: jsfiddle.net/aeGLA/1 । মনে রাখবেন যে, কন্সট্রাকটর Boyহয় না এর প্রোটোটাইপ চেন John। এর প্রোটোটাইপ শৃঙ্খল Johnনিম্নরূপ: Boy.prototype -> Object.prototype -> null
Vidime Vidas

4
" আমি ভেবেছিলাম অবজেক্ট.জেটপ্রোটোটাইপফ (ওজেক্ট) আপত্তিটির নির্মাণকারীর প্রোটোটাইপ ফিরিয়ে দেবে " - হ্যাঁ। ক্ষেত্রে John, তার নির্মাণকারী হয় Boy, এবং এর prototypeসম্পত্তি Boyহয় Boy.prototype। সুতরাং Object.getPrototypeOf(John)ফিরে Boy.prototype
Vidime Vidas

12

পুনরাবৃত্তি ব্যবহার করে একটি ক্লিনার সমাধান:

function getAllPropertyNames (obj) {
    const proto     = Object.getPrototypeOf(obj);
    const inherited = (proto) ? getAllPropertyNames(proto) : [];
    return [...new Set(Object.getOwnPropertyNames(obj).concat(inherited))];
}

সম্পাদনা করুন

আরও জেনেরিক ফাংশন:

function walkProtoChain (obj, callback) {
    const proto     = Object.getPrototypeOf(obj);
    const inherited = (proto) ? walkProtoChain(proto, callback) : [];
    return [...new Set(callback(obj).concat(inherited))];
}

function getOwnNonEnumPropertyNames (obj) {
    return Object.getOwnPropertyNames(obj)
        .filter(p => !obj.propertyIsEnumerable(p));
}

function getAllPropertyNames (obj) {
    return walkProtoChain(obj, Object.getOwnPropertyNames);
}

function getAllEnumPropertyNames (obj) {
    return walkProtoChain(obj, Object.keys);
}

function getAllNonEnumPropertyNames (obj) {
    return walkProtoChain(obj, getOwnNonEnumPropertyNames);
}

এই একই টেম্পলেট Object.getOwnPropertySymbolsইত্যাদি ব্যবহার করে প্রয়োগ করা যেতে পারে etc.


4

সেটগুলির সুবিধা গ্রহণ করা কিছুটা পরিষ্কার সমাধানের দিকে নিয়ে যায়, আইএমও।

const own = Object.getOwnPropertyNames;
const proto = Object.getPrototypeOf;

function getAllPropertyNames(obj) {
    const props = new Set();
    do own(obj).forEach(p => props.add(p)); while (obj = proto(obj));
    return Array.from(props);
}

2

ES6 এ সরাসরি এগিয়ে পুনরাবৃত্তি:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

উদাহরণ রান:


1

কিছু উত্তরাধিকার সূত্রে প্রাপ্ত সমস্ত সম্পত্তি বা পদ্ধতিগুলি পেতে আপনি এর মতো কিছু ব্যবহার করতে পারেন

var BaseType = function () {
    this.baseAttribute = "base attribute";
    this.baseMethod = function() {
        return "base method";
    };
};

var SomeType = function() {
    BaseType();
    this.someAttribute = "some attribute";
    this.someMethod = function (){
        return "some method";
    };
};

SomeType.prototype = new BaseType();
SomeType.prototype.constructor = SomeType;

var instance = new SomeType();

Object.prototype.getInherited = function(){
    var props = []
    for (var name in this) {  
        if (!this.hasOwnProperty(name) && !(name == 'constructor' || name == 'getInherited')) {  
            props.push(name);
        }  
    }
    return props;
};

alert(instance.getInherited().join(","));

4
Object.getInheritedবরং ব্যবহার করা ভাল Object.prototype.getInherited। এটি করা কুৎসিত !(name == 'getInherited')চেকের প্রয়োজনীয়তাও সরিয়ে দেয় । এছাড়াও, আপনার প্রয়োগে propsঅ্যারেতে সদৃশ বৈশিষ্ট্য থাকতে পারে। শেষ অবধি, constructorসম্পত্তি উপেক্ষা করার উদ্দেশ্য কী ?
পauান

কখন অবজেক্ট.জেটইনারাইডেড সত্য হবে? উত্তরাধিকার নিয়ে আটকে থাকায়
রবীন্দ্র বাবু

আইএমএইচও - এগুলি প্রতিবিম্বের অন্তর্ভুক্ত, অবজেক্টের নয়। বা - বিকল্পভাবে - আমি ভাষা অবজেক্ট.কিজ (এসসিআর, [সেটিংস]) থেকে আশা করব যেখানে alচ্ছিক সেটিংস নির্দিষ্ট করে দিতে পারে যদি অ-সংখ্যাযুক্তকে অন্তর্ভুক্ত করা হয়, যদি উত্তরাধিকারী অন্তর্ভুক্ত করা হয়, যদি অগণিত উত্তরাধিকারী অন্তর্ভুক্ত থাকে, যদি নিজের অন্তর্ভুক্ত থাকে , যদি প্রতীকগুলি অন্তর্ভুক্ত করা হয় এবং সম্ভবত উত্তরাধিকারের গভীরতম গভীরতা কোনটি।
ব্রাউন ব্রাউন

ওহ ... অবজেক্ট.এন্ট্রিগুলির জন্য একই। যদিও অবজেক্ট.ভ্যালু সম্পর্কে নিশ্চিত নয়। ...আমরা হব. কেন না.
ব্রাউন ব্রাউন

0

বিষয়টি অধ্যয়নের সময় আমি যে সমাধানটি নিয়ে এসেছি তা এখানে। objঅবজেক্টটির সমস্ত অ-গণনাযোগ্য অ-নিজস্ব সম্পত্তি পেতে TogetProperties(obj, "nonown", "nonenum");

function getProperties(obj, type, enumerability) {
/**
 * Return array of object properties
 * @param {String} type - Property type. Can be "own", "nonown" or "both"
 * @param {String} enumerability - Property enumerability. Can be "enum", 
 * "nonenum" or "both"
 * @returns {String|Array} Array of properties
 */
    var props = Object.create(null);  // Dictionary

    var firstIteration = true;

    do {
        var allProps = Object.getOwnPropertyNames(obj);
        var enumProps = Object.keys(obj);
        var nonenumProps = allProps.filter(x => !(new Set(enumProps)).has(x));

        enumProps.forEach(function(prop) {
            if (!(prop in props)) {
                props[prop] = { own: firstIteration, enum_: true };
            }           
        });

        nonenumProps.forEach(function(prop) {
            if (!(prop in props)) {
                props[prop] = { own: firstIteration, enum_: false };
            }           
        });

        firstIteration = false;
    } while (obj = Object.getPrototypeOf(obj));

    for (prop in props) {
        if (type == "own" && props[prop]["own"] == false) {
            delete props[prop];
            continue;
        }
        if (type == "nonown" && props[prop]["own"] == true) {
            delete props[prop];
            continue;
        }

        if (enumerability == "enum" && props[prop]["enum_"] == false) {
            delete props[prop];
            continue;
        }
        if (enumerability == "nonenum" && props[prop]["enum_"] == true) {
            delete props[prop];
        }
    }

    return Object.keys(props);
}

0
function getNonEnumerableNonOwnPropertyNames( obj ) {
    var oCurObjPrototype = Object.getPrototypeOf(obj);
    var arReturn = [];
    var arCurObjPropertyNames = [];
    var arCurNonEnumerable = [];
    while (oCurObjPrototype) {
        arCurObjPropertyNames = Object.getOwnPropertyNames(oCurObjPrototype);
        arCurNonEnumerable = arCurObjPropertyNames.filter(function(item, i, arr){
            return !oCurObjPrototype.propertyIsEnumerable(item);
        })
        Array.prototype.push.apply(arReturn,arCurNonEnumerable);
        oCurObjPrototype = Object.getPrototypeOf(oCurObjPrototype);
    }
    return arReturn;
}

ব্যবহারের উদাহরণ:

function MakeA(){

}

var a = new MakeA();

var arNonEnumerable = getNonEnumerableNonOwnPropertyNames(a);

0

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

Object.getOwnPropertyNames(Object.getPrototypeOf(obj));

0

আমার ব্যক্তিগত পছন্দগুলিতে একটি বাস্তবায়ন :)

function getAllProperties(In, Out = {}) {
    const keys = Object.getOwnPropertyNames(In);
    keys.forEach(key => Object.defineProperty(In, key, {
        enumerable: true
    }));
    Out = { ...In, ...Out };

    const Prototype = Object.getPrototypeOf(In);
    return Prototype === Object.prototype ? Out : getAllProperties(Proto, Out);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.