ES6 / 2015 এ নাল-নিরাপদ সম্পত্তি অ্যাক্সেস (এবং শর্তসাপেক্ষ অ্যাসাইনমেন্ট)


149

সেখানে একটি হল null-safe সম্পত্তি এক্সেস ES6 (ES2015 / JavaScript.next / সঙ্গতি নিয়ন্ত্রণ করে) মত (নাল প্রসারণ / অস্তিত্ব) অপারেটর ?.মধ্যে CoffeeScript উদাহরণস্বরূপ? বা এটি ES7 এর জন্য পরিকল্পনা করা হয়েছে?

var aThing = getSomething()
...
aThing = possiblyNull?.thing

এটি মোটামুটি মত হবে:

if (possiblyNull != null) aThing = possiblyNull.thing

আদর্শভাবে সমাধানটি যদি হয় তবে (এমনকি undefined) বরাদ্দ করা উচিত নয়aThingpossiblyNullnull


3
@naomik নাল পরীক্ষণ এই ধরনের খুবই উপযোগী হতে পারে যদি বিবৃতি যেখানে আপনি একটি গভীরভাবে নেস্টেড সম্পত্তি জন্য চেক করছি যেমন, if( obj?.nested?.property?.value )পরিবর্তেif( obj && obj.nested && obj.nested.property && obj.nested.property.value )
শন ওয়ালশ

@ স্যানওয়ালশ যদি আপনার বস্তুগুলি গভীরভাবে বাসা বেঁধে থাকে বা যদি আপনার ফাংশনগুলি আপনার বস্তুগুলিতে গভীরভাবে এটি খনন করে থাকে তবে আপনার অ্যাপ্লিকেশনটিতে সম্ভবত আরও বেশ কয়েকটি সমস্যা রয়েছে।
আপনাকে ধন্যবাদ

1
তুলনা var appConfig = loadConfig(config, process.env); connect(appConfig.database);করার জন্য connect(config)connectপুরো configঅবজেক্টটি পাস করার পরিবর্তে আপনি অনেক সহজ বস্তুটি পাস করতে পারেন conf.username, conf.passwordযেমন config[process.env]?.database?.username, কিছু চেষ্টা করার পরিবর্তে আপনি ব্যবহার করতে পারেন config[process.env]?.database?.password। রেফারেন্স: ডিমিটারের আইন
আপনাকে ধন্যবাদ

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

4
@ ননমিক যতক্ষণ না ভাষা বাসা বেঁধে দেওয়া জিনিসগুলিকে সমর্থন করে ততক্ষণ এটি এখনও একটি দরকারী বৈশিষ্ট্য - আপনি বা আমি নিজেই অ্যাপটির আর্কিটেকচারটি যা ভাবি না কেন। একটি সরু হিসাবে, এর মতো জটিল অবজেক্টের গ্রাফগুলি ওআরএমগুলিতে খুব সাধারণ যেগুলি একটি জটিল ডেটা মডেল তৈরি করে।
শন ওয়ালশ

উত্তর:


98

আপডেট (2020-01-31): মনে হচ্ছে লোকেরা এখনও এটি সন্ধান করছে, এখানে বর্তমান গল্পটি রয়েছে:

আপডেট (2017-08-01): আপনি যদি অফিশিয়াল প্লাগইন ব্যবহার করতে চান তবে আপনি নতুন ট্রান্সফর্মের সাহায্যে বাবেল 7 এর আলফা বিল্ড চেষ্টা করতে পারেন। আপনার মাইলেজ পরিবর্তিত হতে পারে

https://www.npmjs.com/package/babel-plugin-transform-optional-chaining

মূল :

একটি বৈশিষ্ট্য যা সম্পূর্ণ করে যা বর্তমানে প্রথম পর্যায়ে রয়েছে: Chaচ্ছিক চেইনিং।

https://github.com/tc39/proposal-optional-chaining

আপনি যদি আজ এটি ব্যবহার করতে চান তবে একটি ব্যাবেল প্লাগইন রয়েছে যা এটি সম্পাদন করে।

https://github.com/davidyaha/ecmascript-optionals-proposal


আমি কি সঠিকভাবে বুঝতে পারি যে এতে শর্তযুক্ত কার্যভার অন্তর্ভুক্ত নেই? কোন ক্ষেত্রে street = user.address?.streetসেট করবে street?
14 ᆺ ᆼ

1
আসলে দুর্ভাগ্যজনকভাবে আমি মনে করি আপনি ঠিক বলেছেন Street আমি মনে করি নিযুক্ত করা হবে undefinedতবে কমপক্ষে এটি অপরিজ্ঞাতকৃত বৈশিষ্ট্যগুলিতে অ্যাক্সেসের চেষ্টা করার চেষ্টা করবে না।
মৌলিক দিনগুলি

2
এটি দেখে মনে হচ্ছে আপনি বাম হাতের চালককে অপারেটর করতে পারেন এবং এটি যদি অপরিবর্তিত কোনও কিছু দেখায় তবে ডান হাতটি মূল্যায়ন করা হয় না। বাবেল প্লাগইনটি কিছুটা আলাদা হতে পারে, এটি এখনও আমার বেশি পরীক্ষিত হয়নি।
মৌলিক দিনগুলি

1
বাম-হাতের শর্তাধীন অ্যাসাইনমেন্ট সম্পর্কে =, দেখে মনে হচ্ছে এটি বর্তমানে অফিশিয়াল স্পেসে সমর্থিত নয়। github.com/tc39/proposal-optional-chaining#not-supported
বেসডেডস

1
2020 সালের মে হিসাবে, বর্তমান ব্রাউজারগুলি এবং টাইপস্রিপ্টগুলি দেখে মনে হচ্ছে এটি কার্যকর হয়েছে!
জোশ ডিহল

65

এটা এত সুন্দর না? অপারেটর, তবে একই ফলাফল অর্জন করতে আপনি করতে পারেন:

user && user.address && user.address.postcode

যেহেতু nullএবং undefinedউভয় মিথ্যা মানগুলি ( এই রেফারেন্সটি দেখুন ), &&অপারেটরের পরে সম্পত্তি কেবল তখনই অ্যাক্সেস করা যায় যদি নজিরটি নাল বা অপরিজ্ঞাত না হয়।

বিকল্পভাবে, আপনি এর মতো একটি ফাংশন লিখতে পারেন:

function _try(func, fallbackValue) {
    try {
        var value = func();
        return (value === null || value === undefined) ? fallbackValue : value;
    } catch (e) {
        return fallbackValue;
    }
}

ব্যবহার:

_try(() => user.address.postcode) // return postcode or undefined 

অথবা, একটি ফ্যালব্যাক মান সহ:

_try(() => user.address.postcode, "none") // return postcode or a custom string

ঠিক এখনই আমার এই প্রশ্নটি স্পষ্ট করা উচিত, প্রধান জিনিসটি আমি শর্তসাপেক্ষ অ্যাসাইনমেন্ট ছিল
3 :3

এটির একটি ছদ্মবেশ; বিপরীতটি নিরাপদে খুঁজে পেতে, আপনি ব্যবহার করতে পারেন !(user && user.address && user.address.postcode) :)
rob2d

foo && foo.bar && foo.bar.quux ...একটি বৃহত কোডবেসে এটি কুৎসিত এবং প্রচুর জটিলতা যুক্ত করেছে যা আপনি এড়ানো ভাল।
স্কাইলার সেভল্যান্ড

1
এটি ইন্টারনেটে আমি খুঁজে পেয়েছি সবচেয়ে পরিষ্কার সমাধান। আমি _get<T>(func: () => T, fallbackValue?: T) :T
টাইপস্ক্রিপ্ট

3
যদি user.address.postcodeঅপরিজ্ঞাত থাকে তবে পরিবর্তে _try(() => user.address.postcode, "")ফিরে আসবে । সুতরাং কোড একটি ব্যতিক্রম উত্থাপন করবে। undefined""_try(() => user.address.postcode, "").length
আলেকজান্ডার চেন

33

না। আপনি জাভাস্ক্রিপ্টে এর জন্য লড্যাশ # গিটে বা এর মতো কিছু ব্যবহার করতে পারেন ।


4
এটি ES7 এ যুক্ত করার প্রস্তাব আছে কি?
26 ᆺ ᆼ

1
কোনটির মুখোমুখি হয়নি।
গিরাফা

3
@ পিটারভার্গা: অনেক। খুব আলোচনা। ব্যাকরণ এই বৈশিষ্ট্যটির জন্য খুব সহজ জিনিস নয়
বার্গি

1
lodash.getঅবিচ্ছিন্নভাবে কিছুটা আলাদা এটি শর্তসাপেক্ষ অ্যাসাইনমেন্টটি করতে পারে না।
ᆼ ᆺ ᆼ

17

নিরাপদ সম্পত্তি অ্যাক্সেসের জন্য ভ্যানিলা বিকল্প

(((a.b || {}).c || {}).d || {}).e

সর্বাধিক সংক্ষিপ্ত শর্তসাপেক্ষ অ্যাসাইনমেন্ট সম্ভবত এটিই হবে

try { b = a.b.c.d.e } catch(e) {}

সুতরাং কিভাবে আপনি এই পদ্ধতি ব্যবহার করে প্রশ্নে অ্যাসাইনমেন্ট লিখবেন? possiblyNullসংজ্ঞাটি সংজ্ঞায়িত / সংজ্ঞায়িত না করা সত্ত্বেও আপনার কি শর্তযুক্ত প্রয়োজন নেই null?
ᆼ ᆺ ᆼ

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

অবশ্যই, উদাহরণস্বরূপ কফিস্ক্রিপ্ট এরও রয়েছে||=
5 ᆺ ᆼ

এমনকি আমার প্রথম চিন্তাও ছিল (((a.b || {}).c || {}).d || {}).e। তবে এটি আরও সুনির্দিষ্ট হবে((((a || {}).b || {}).c || {}).d || {}).e
ইসমাইলস

6

না, ES6 এ কোনও নাল প্রচারের অপারেটর নেই। আপনি একটি পরিচিত নিদর্শন সঙ্গে যেতে হবে ।

আপনি ডেস্ট্রাকচারিং ব্যবহার করতে সক্ষম হতে পারেন, যদিও:

({thing: aThing} = possiblyNull);

ES7 এ এই জাতীয় অপারেটর যুক্ত করার জন্য অনেকগুলি আলোচনা রয়েছে (উদাঃ এটি ), তবে সত্যিই তা গ্রহণ করেনি।


এটি আশাব্যঞ্জক বলে মনে হয়েছিল, তবে বাবেল এটির সাথে কমপক্ষে যা করেন তা ন্যায়বিচারের থেকে আলাদা নয়aThing = possiblyNull.thing
20 ᆺ ᆼ

1
@ পিটারভার্গা: ওফস, আপনি ঠিক বলেছেন, সম্পত্তি বিদ্যমান না থাকলে ধ্বংসাত্মক কাজ করে তবে বস্তুটি যখন থাকে না তখন null। আপনাকে একটি ডিফল্ট মান সরবরাহ করতে হবে, প্রায় এই ধরণের মতো তবে আরও বিভ্রান্তিকর বাক্য গঠন সহ।
বার্গি

4

এখানে তালিকাটি দেখতে গিয়ে বর্তমানে ইকমাস্ক্রিপ্টে নিরাপদ ট্র্যাভারসাল যুক্ত করার কোনও প্রস্তাব নেই। সুতরাং এটি করার জন্য কেবল কোনও দুর্দান্ত উপায়ই নয়, তবে এটি ভবিষ্যতে যোগ করা যায় না।


1
// Typescript
static nullsafe<T, R>(instance: T, func: (T) => R): R {
    return func(instance)
}

// Javascript
function nullsafe(instance, func) {
    return func(instance);
};

// use like this
const instance = getSomething();
let thing = nullsafe(instance, t => t.thing0.thing1.thingx);

1

?.Ptionচ্ছিক চেইনিং এবং নুলিশ কোয়েলসিং??

আপনি এখন সরাসরি ব্যবহার করতে পারেন ?.নিরাপদে অস্তিত্বের জন্য পরীক্ষা ইনলাইন । সমস্ত আধুনিক ব্রাউজার এটি সমর্থন করে।

?? পূর্বনির্ধারিত বা শূন্য হলে ডিফল্ট মান সেট করতে ব্যবহার করা যেতে পারে।

aThing = possiblyNull ?? aThing
aThing = a?.b?.c ?? possiblyNullFallback ?? aThing

যদি কোনও সম্পত্তি বিদ্যমান থাকে, ?.পরবর্তী চেকটিতে এগিয়ে যায় বা বৈধ মানটি দেয়। যে কোনও ব্যর্থতা অবিলম্বে শর্ট সার্কিট হয়ে ফিরে আসবে undefined

const example = {a: ["first", {b:3}, false]}

example?.a  // ["first", {b:3}, false]
example?.b  // undefined

example?.a?.[0]     // "first"
example?.a?.[1]?.a  // undefined
example?.a?.[1]?.b  // 3

domElement?.parentElement?.children?.[3]?.nextElementSibling

null?.()                // undefined
validFunction?.()       // result
(() => {return 1})?.()  // 1

একটি ডিফল্ট সংজ্ঞায়িত মান নিশ্চিত করতে, আপনি ব্যবহার করতে পারেন ??। আপনার যদি প্রথম সত্যবাদী মান প্রয়োজন হয় তবে আপনি এটি ব্যবহার করতে পারেন ||

example?.c ?? "c"  // "c"
example?.c || "c"  // "c"

example?.a?.[2] ?? 2  // false
example?.a?.[2] || 2  // 2

যদি আপনি কোনও মামলা পরীক্ষা না করেন তবে অবশ্যই বাম দিকের সম্পত্তি থাকা উচিত। যদি তা না হয় তবে এটি ব্যতিক্রম ছুঁড়ে ফেলবে।

example?.First         // undefined
example?.First.Second  // Uncaught TypeError: Cannot read property 'Second' of undefined

?.ব্রাউজার সমর্থন - 78%, জুলাই 2020

??ব্রাউজার সমর্থন - 78%

মজিলা ডকুমেন্টেশন

-

লজিকাল নালিশ নিয়োগ, 2020+ সমাধান

নতুন অপারেটরগুলি বর্তমানে ব্রাউজারগুলিতে যুক্ত করা হচ্ছে ??=, ||=এবং &&=। তারা আপনি যা সন্ধান করছেন তা পুরোপুরি করে না, তবে আপনার কোডের লক্ষ্য অনুসারে একই ফলাফল হতে পারে।

দ্রষ্টব্য: পাবলিক ব্রাউজার সংস্করণগুলিতে এগুলি এখনও সাধারণ নয় , তবে বাবেলকে ভালভাবে স্থানান্তর করা উচিত। প্রাপ্যতা পরিবর্তন হিসাবে আপডেট হবে।

??=বাম দিকটি অপরিজ্ঞাত বা নাল কিনা তা পরীক্ষা করে দেখেছে, ইতিমধ্যে সংজ্ঞায়িত হলে শর্ট সার্কিট। যদি তা না হয় তবে বাম দিকটি ডান পাশের মান নির্ধারিত হয়। ||=এবং &&=অনুরূপ, তবে ||এবং &&অপারেটরগুলির উপর ভিত্তি করে ।

বেসিক উদাহরণ

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

বস্তু / অ্যারে উদাহরণ

let x = ["foo"]
let y = { foo: "fizz" }

x[0] ??= "bar"  // "foo"
x[1] ??= "bar"  // "bar"

y.foo ??= "buzz"  // "fizz"
y.bar ??= "buzz"  // "buzz"

x  // Array [ "foo", "bar" ]
y  // Object { foo: "fizz", bar: "buzz" }

ব্রাউজার সমর্থন 2020 জুলাই - .03%

মজিলা ডকুমেন্টেশন


1
প্রশ্ন শর্তসাপেক্ষ নিয়োগ সম্পর্কে হয়
ᆼ ᆺ ᆼ

?.এবং এর সাথে কয়েকটি উদাহরণ যুক্ত করা হয়েছে এবং ??একটি আসন্ন সমাধান যা আপনার পরিস্থিতির জন্য কাজ করতে পারে work সেরা বর্তমান সমাধানটি কেবলমাত্র করণীয়aThing = possiblyNull?.thing ?? aThing
গিবল্ট

0

একটি নিরাপদ গভীর get পদ্ধতিটি আন্ডারস্কোর.জেএস এর জন্য প্রাকৃতিক ফিটের মতো বলে মনে হচ্ছে তবে সেখানে সমস্যাটি স্ট্রিং প্রোগ্রামিং এড়িয়ে চলেছে। স্ট্রিং প্রোগ্রামিং এড়ানোর জন্য @ ফিলিপের উত্তরটি সংশোধন করা (বা কমপক্ষে প্রান্তের কেসগুলিকে কলারের দিকে ঠেলে দেয়):

function safeGet(obj, props) {
   return (props.length==1) ? obj[keys[0]] :safeGet(obj[props[0]], props.slice(1))
}

উদাহরণ:

var test = { 
  a: { 
    b: 'b property value',
    c: { }
  } 
}
safeGet(test, ['a', 'b']) 
safeGet(test, "a.b".split('.'))  

প্যারাফ্রেজ করতে রিক: এটি কেবল অতিরিক্ত পদক্ষেপ সহ স্ট্রিং প্রোগ্রামিংয়ের মতো শোনাচ্ছে।
টোক্কোভিল

1
লোগাশ এখন গভীর গেট / সেট প্রয়োগ করে _.get(obj, array_or_dotstring)
প্রোটোটাইপ

1
তবে জাভা স্ক্রিপ্ট বিন্দু এবং স্ট্রিং অ্যাকসেসর স্বরলিপিটিও ন্যায্যভাবে বলতে গেলে স্ট্রিং প্রোগ্রামিং, obj.a.b.cবনামobj['a']['b']['c']
প্রোটোটাইপ

1
কোথা keysথেকে আসছে?
লেবি রবার্টস

-2

আমি জানি এটি একটি জাভাস্ক্রিপ্টের প্রশ্ন, তবে আমি মনে করি যে রুবি অনুরোধকৃত সমস্ত উপায়ে এটি পরিচালনা করে, তাই আমি মনে করি এটি একটি প্রাসঙ্গিক বিষয় উল্লেখযোগ্য।

.&, try এবং&& এর শক্তি এবং সম্ভাব্য সমস্যা রয়েছে। এই বিকল্পগুলির এখানে দুর্দান্ত রান: http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/

TLDR; রুবিবাদীদের উপসংহারটি হ'ল digউভয় চোখের উপরে সহজ এবং আরও শক্তিশালী গ্যারান্টি a বা nullনির্ধারিত হবে।

এখানে টাইপস্ক্রিপ্টে একটি সাধারণ imeplementation:

export function dig(target: any, ...keys: Array<string>): any {
  let digged = target
  for (const key of keys) {
    if (typeof digged === 'undefined') {
      return undefined // can also return null or a default value
    }
    if (typeof key === 'function') {
      digged = key(digged)
    } else {
      digged = digged[key]
    }
  }
  return digged
}

এটি নেস্টিং এবং হ্যান্ডলস ফাংশনগুলির কোনও গভীরতার জন্য ব্যবহার করা যেতে পারে।

a = dig(b, 'c', 'd', 'e');
foo = () => ({});
bar = dig(a, foo, 'b', 'c')

tryপূর্ববর্তী উত্তর দেখানো পদ্ধতির সমান জাতীয় পড়া চমৎকার। এটির জন্য লুপিংয়েরও প্রয়োজন হয় না, যা এই বাস্তবায়নের এক অপূর্ণতা।


আমি এই উত্তরটি এখানে একটি মজাদার / সম্পূর্ণ / বিকল্প সমাধান হিসাবে উপস্থাপন করেছি খ / সি আমার পছন্দ মতো রুবি সিনট্যাকটিকাল চিনির সাথে এটি করে। সম্প্রদায়ের জন্য কেবল এটি প্রকাশ করা - আরও একবার ভোট দিন এবং আমি আনন্দের সাথে এই পোস্টটি মুছব। চিয়ার্স!
দ্য উথারসাইড

সত্যিই শীতল ECMAScript2019 দেখতে রুবির মতো " ptionচ্ছিক চেইনিং" এর জন্য দুর্দান্ত প্রস্তাব রয়েছে: github.com/tc39/proposal-optional-chaining এটি আজ বাবেল প্লাগইনের মাধ্যমে উপলভ্য, এবং এটি কোনও বস্তুতে পদ্ধতি কল করার জন্যও কাজ করে: babeljs.io / ডকস / এন / ব্যাবেল-প্লাগইন-প্রস্তাব-
alচ্ছিক

-5

আমি ভেবেছিলাম এই প্রশ্নটির জন্য 2018 এর জন্য কিছুটা রিফ্রেশ দরকার। এটি কোনও লাইব্রেরি ব্যবহার Object.defineProperty()না করে দুর্দান্তভাবে করা যায় এবং নীচে ব্যবহার করা যেতে পারে:

myVariable.safeGet('propA.propB.propC');

এমডিএন-তে নথিবদ্ধ হিসাবে, পদ্ধতিটির জন্য এখন উপলব্ধ writeableএবং enumerableসংজ্ঞাগুলির কারণে আমি এটি নিরাপদ (এবং জেএস-নৈতিক) বিবেচনা করিdefinePropertyObject

নীচে ফাংশন সংজ্ঞা:

Object.defineProperty(Object.prototype, 'safeGet', { 
    enumerable: false,
    writable: false,
    value: function(p) {
        return p.split('.').reduce((acc, k) => {
            if (acc && k in acc) return acc[k];
            return undefined;
        }, this);
    }
});

এটি প্রদর্শনের জন্য আমি একটি জেএসবিনকে একত্রিত করেছি কনসোল আউটপুট সঙ্গে। নোট করুন যে jsBin সংস্করণে আমি খালি মানগুলির জন্য একটি কাস্টম ব্যতিক্রমও যুক্ত করেছি। এটি alচ্ছিক, এবং তাই আমি এটিকে উপরের সংক্ষিপ্ত সংজ্ঞা থেকে বাদ দিয়েছি।

উন্নতি স্বাগত জানানো হয়


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