IT

ES6 / 2015의 안전하지 않은 속성 액세스 및 조건부 할당

lottoking 2020. 6. 28. 18:03
반응형

ES6 / 2015의 안전하지 않은 속성 액세스 및 조건부 할당


거기 nullES6 (ES2015 / JavaScript.next / 하모니) 등의 -safe 속성 액세스 (null의 전파 / 유) 연산자 ?.커피 스크립트 예는? 아니면 ES7을 계획하고 있습니까?

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

이것은 대략 다음과 같습니다.

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

이상적 솔루션 (심지어 할당해서는 안됩니다 undefined)로 aThing하면 possiblyNullISnull


업데이트 (2019-06-27) : 사람들이 여전히 이것을 찾고있는 것 같습니다. 현재 이야기는 다음과 같습니다.

업데이트 (2017-08-01) : 공식 플러그인을 사용하려면 새로운 변형으로 Babel 7의 알파 빌드를 시도 할 수 있습니다. 귀하의 마일리지가 다를 수 있습니다

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

원본 :

현재 1 단계에있는 기능 : 옵션 체인.

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

오늘 사용하고 싶다면 그것을 수행하는 Babel 플러그인이 있습니다.

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


?만큼 좋지 않습니다. 연산자이지만 비슷한 결과를 얻으려면 다음을 수행하십시오.

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

nullundefined둘 다 잘못된이므로 ( 이 참조 참조 ) &&선행 연산자가 null이거나 정의되지 않은 경우에만 연산자 뒤의 속성에 액세스합니다.

또는 다음과 같은 함수를 작성할 수 있습니다.

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

아니요 . JavaScript에서 lodash # get 또는 이와 유사한 것을 사용할 수 있습니다 .


안전한 자산 접근을위한 바닐라 대안

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

가장 간결한 조건부 할당은 아마도

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


아니요, ES6에는 null 전파 연산자가 없습니다. 알려진 패턴 중 하나를 사용해야 합니다.

그러나 다음과 같은 구조 조정을 사용할 수 있습니다.

({thing: aThing} = possiblyNull);

ES7에서 그러한 연산자를 추가하기위한 많은 토론 (예 : this ) 있지만 실제로 이륙 한 사람은 없습니다.


여기 의 목록으로 이동하면 현재 Ecmascript에 안전한 순회를 추가 할 제안이 없습니다. 따라서이를 수행 할 수있는 좋은 방법은 없을뿐만 아니라 미래에도 추가되지는 않을 것입니다.


안전한 deep get 메소드는 underscore.js에 자연스럽게 맞는 것처럼 보이지만 문제는 문자열 프로그래밍을 피하는 것입니다. 문자열 프로그래밍을 피하기 위해 @Felipe의 답변을 수정하십시오 (또는 적어도 사례를 호출자에게 다시 푸시합니다).

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('.'))  

// 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);

나는 이것이 JavaScript 질문이라는 것을 알고 있지만 Ruby가 요청한 모든 방식으로 이것을 처리한다고 생각하므로 관련 참조 지점이라고 생각합니다.

.&,, try&&에는 강점과 잠재적 인 함정이 있습니다. 이러한 옵션에 대한 자세한 설명은 다음과 같습니다. http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/

TLDR; Rubyists의 결론은 dig눈에 더 쉽고 이나 가치null 가 부여 될 것이라는 더 강한 보증입니다 .

TypeScript의 간단한 구현은 다음과 같습니다.

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
}

This can be used for any depth of nesting and handles functions.

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

The try approach is equally nice to read in JS, as shown in previous answers. It also does not require looping, which is one drawback of this implementation.


I thought this question needed a bit of a refresh for 2018. This can be done nicely without any libraries using Object.defineProperty() and can be used as follows:

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

I consider this safe (and js-ethical) because of the writeable and enumerable definitions now available for the defineProperty method of Object, as documented in MDN

function definition below:

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);
    }
});

I've put together a jsBin with console output to demonstrate this. Note that in the jsBin version I've also added a custom exception for empty values. This is optional, and so I've left it out of the minimal definition above.

Improvements are welcomed

참고URL : https://stackoverflow.com/questions/32139078/null-safe-property-access-and-conditional-assignment-in-es6-2015

반응형