자바 스크립트 개체 속성의 기본값 설정


82

다음과 같이 javascript 객체의 기본 속성을 설정하는 방법이 있습니까?

var emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue

IE는 무시할 수 있습니다. Chrome 프레임은 그 두통을 덜어주었습니다.


존재하지 않는 모든 속성 또는 알려진 속성 이름?
js1568 2011

답변:


115

몇 년 전에 질문 한 이후로 상황이 잘 진행되었습니다.

프록시는 ES6의 일부입니다. 다음 예제는 Chrome, Firefox, Safari 및 Edge 에서 작동합니다 .

var handler = {
  get: function(target, name) {
    return target.hasOwnProperty(name) ? target[name] : 42;
  }
};

var p = new Proxy({}, handler);

p.answerToTheUltimateQuestionOfLife; //=> 42

Mozilla의 Proxies 문서에서 더 많은 것을 읽으십시오 .


Internet Explorer (Edge 이전)를 지원할 계획이라면 운 이 좋지 않습니다 . caniuse.com/#search=proxy 또한 polyfill github.com/tvcutsem/harmony-reflect 는 IE를 지원하지 않습니다
Tiagojdferreira

21
축하, 당신은 적립 한 피닉스 (골드 배지 : 적어도 자신의 질문 중 하나를 대답 년 후, 답변으로 적어도 가장 인기있는 대답의 투표 수를 두 배로 있음)
저 친구

Object.withDefault = (defaultValue, o = {}) => new Proxy (o, {get : (o, k) => (k in o)? o [k] : defaultValue}); o = Object.withDefault (42); ox // => 42 ox = 10 ox // => 10 o.xx // => 42
Vlad V

따라서 Proxy를 사용한다는 Object.getEntries것은 Proxy에서 호출 할 수 없다는 의미이기도합니다. (
Meredith

1
의미하는 경우 Object.entries처리기를 수정하여 액세스 할 때 속성을 설정할 수 있습니다. 변경 return target.hasOwnProperty(name) ? target[name] : 42;if (!target.hasOwnProperty(name)) target[name] = 42; return target[name];.
dosentmatter

28

자바 스크립트에서이를 설정하는 방법은 없습니다. undefined존재하지 않는 속성을 반환 하는 것은 핵심 자바 스크립트 사양의 일부입니다. 이 유사한 질문에 대한 토론을 참조하십시오 . 내가 거기에서 제안했듯이 한 가지 접근 방식 (정말 추천 할 수는 없지만)은 전역 getProperty함수 를 정의하는 것입니다 .

function getProperty(o, prop) {
    if (o[prop] !== undefined) return o[prop];
    else return "my default";
}

var o = {
    foo: 1
};

getProperty(o, 'foo'); // 1
getProperty(o, 'bar'); // "my default"

그러나 이것은 다른 사람들이 읽기 어려운 비표준 코드로 이어질 것이며 정의되지 않은 값을 기대하거나 원하는 영역에서 의도하지 않은 결과를 초래할 수 있습니다. 이동하면서 확인하는 것이 좋습니다.

var someVar = o.someVar || "my default";

10
경고 : var someVar = o.someVar || "my default";o.someVar가 채워지지만 false로 평가되면 잠재적으로 예상치 못한 결과가 발생합니다 (예 : null, 0, ""). someVar = o.someVar === undefined ? o.someVar : "my default";더 좋을 것입니다. 나는 일반적으로 사용하는 ||기본도를 평가할 때 혼자 false. (e.g. o.someVar || 0`)
Shanimal

5
그것은 좋은 점입니다. 이것은 false-y 값이 유효한 입력 인 곳에서는 작동하지 않으며,이 패턴을 사용할 때 그것을 고려해야합니다. 하지만 더 자주는 아니지만, 명시 적으로 설정 속성 치료를 의미한다 null또는 false이 두가지 임무를 수행하는 경우에 설정되지 않은 속성과 동일한 방법을. 그러나 경고는 공정합니다.
nrabinowitz

5
@Shanimal 귀하의 예제는 잘못된 방법입니다 someVar = o.someVar === undefined ? "my default" : o.someVar;. 사소한 문제 일 뿐이지 만 코드를 처음 시도했을 때 약간의 문제가 발생했습니다 ;-)
Metalskin

예 @Metalskin 우리는 정의되지 않은 값을 신경 쓰지 않겠습니까? 롤. 죄송합니다, 잘하면 실수 : 당신에게 너무 많은 시간을 요하지 않았다
Shanimal

28

사용 destructuring (새 ES6에서)

Mozila의 훌륭한 문서 와 구문을 내가 할 수있는 것보다 더 잘 설명 하는 환상적인 블로그 게시물 이 있습니다.

질문에 답하려면

var emptyObj = {};
const { nonExistingAttribute = defaultValue } = emptyObj;
console.log(nonExistingAttribute); // defaultValue

더 나아 가기

이 변수의 이름을 바꿀 수 있습니까 ? 확실한!

const { nonExistingAttribute: coolerName = 15} = emptyObj;
console.log(coolerName); // 15

중첩 된 데이터는 어떻습니까? 가져와!

var nestedData = {
    name: 'Awesome Programmer',
    languages: [
        {
            name: 'javascript',
            proficiency: 4,
        }
    ],
    country: 'Canada',
};

var {name: realName, languages: [{name: languageName}]} = nestedData ;

console.log(realName); // Awesome Programmer
console.log(languageName); // javascript

11

이것은 확실히 프로토 타입 기반 개체의 일반적인 사용처럼 들립니다.

// define a new type of object
var foo = function() {};  

// define a default attribute and value that all objects of this type will have
foo.prototype.attribute1 = "defaultValue1";  

// create a new object of my type
var emptyObj = new foo();
console.log(emptyObj.attribute1);       // outputs defaultValue1

console.log (emptyObj)를 호출하면 {}를 반환합니다. not {attribute1 : 'defaultValue1'}
throrin19

2
예, attribute1: defaultValue1은 프로토 타입에 있고 console.log는 프로토 타입이 아닌 최상위 개체에 설정된 항목 만 열거 하기 때문 입니다. 하지만 가치는 내 console.log(emptyObj.attribute1)쇼 처럼 거기에 있습니다 .
jfriend00 2013

맞지만 JSON.stringify(emptyobj). 이 문제에 대한 응답으로 모든 속성을 반환하는 메서드를 만들어야했습니다
throrin19

11

내 코드는 다음과 같습니다.

function(s){
    s = {
        top: s.top || 100,    // default value or s.top
        left: s.left || 300,  // default value or s.left
    }
    alert(s.top)
}

1
PHP에서하는 것과 비슷하기 때문에이 솔루션이 가장 마음에 듭니다. function foo( array $kwargs = array() ) { // Fill in defaults for optional keyworded arguments. $kwargs += array( 'show_user' => true, 'show_links' => false, ); ...
Mike Finch

10

이것을 달성하는 방법은 object.assign기능입니다.

const defaultProperties = { 'foo': 'bar', 'bar': 'foo' };
const overwriteProperties = { 'foo': 'foo' };
const newObj = Object.assign({}, defaultProperties, overwriteProperties);
console.log(defaultProperties);  // {"foo": "bar", "bar": "foo"}
console.log(overwriteProperties);  // { "foo": "foo" };
console.log(newObj);  // { "foo": "foo", "bar": "foo" }

5
당신은 또한의 값을 덮어 쓰는이 이렇게 overwriteProperties올바른 방법은 다음과 같습니다const newObj = Object.assign({}, defaultProperties, overwriteProperties)
시스코 Puga

6

가장 간단한 접근 방식은 Object.assign.

이 클래스가있는 경우 :

class MyHelper {
    constructor(options) {
        this.options = Object.assign({
            name: "John",
            surname: "Doe",
            birthDate: "1980-08-08"
        }, options);
    }
}

다음과 같이 사용할 수 있습니다.

let helper = new MyHelper({ name: "Mark" });
console.log(helper.options.surname); // this will output "Doe"

문서 (폴리 필 포함) : https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Object/assign


5

또는 이것을 시도 할 수 있습니다

dict = {
 'somekey': 'somevalue'
};

val = dict['anotherkey'] || 'anotherval';

15
나쁜 생각 DICT [ 'anotherkey는'] 0 인 경우
레이 톨

: 어쩌면 당신이 고려해야 codereadability.com/...
ebragaparah

@RayToal 그럼 그걸 고치지 않겠 String()습니까? 에서와 같이 :val = dict[String('anotherkey')] || 'anotherval';
Godstime Osarobo

아뇨, 미안합니다. 같은 문제입니다. 첫 번째 수행을 시도 d = {x: 1, y: 0}한 후 d['y'] || 100그 다음 인 아이디어를 시도하지 그것은 잘못 (100)을 제공합니다 d[String('y')] || 100- 그것은 여전히 이 0 줘야 할 때 부적절 (100)을 제공합니다
레이 톨

4

가장 간단한 솔루션 :

dict = {'first': 1,
        'second': 2,
        'third': 3}

지금,

dict['last'] || 'Excluded'

기본값 인 '제외됨'을 반환합니다.


3
약간 다른 사전이 있으면 실패합니다.dict = {'first': 0, 'second': 1, 'third': 2}
Vlad V

1
이것은 존재하지 않을 수도있는 가치를 연결하는 좋은 방법이기도합니다. 예를 들면 a.b.c.d. A, D, 또는 c가 정의되지 않은 경우 오류를 공격하지만, 당신은 할 수(((a || {}).b || {}).c || {}).d) || "default"
hobberwickey

3

이것은 나에게 가장 간단하고 읽기 쉬운 방법으로 보입니다.

let options = {name:"James"}
const default_options = {name:"John", surname:"Doe"}

options = Object.assign({}, default_options, options)

Object.assign () 참조


나는 밑줄 라이브러리에 _.defaults (object, * defaults) 메서드가 있다고 대답하려고했지만 라이브러리 없이도 대답이 동일합니다!
DaniCE

2

어제 Object.__noSuchMethod__속성에 대해 언급 한 기사를 보았습니다 . JavascriptTips 사용해 볼 기회가 없었기 때문에 브라우저 지원에 대해 모르겠지만 어떤 식 으로든 사용할 수 있습니까?


그 페이지도 봤는데, 우리는 같은 HN 기사를 읽었을 것입니다. 그래도 방법 만. defineGetter로 할 수 는 있지만 불행히도 ECMA5에는 없습니다. 그들은 내 관점에서 더 나쁜 다른 getter / setter 접근 방식을 사용하지 않았습니다 (사전에 속성 정의가 필요함).
sandstrom 2011-07-07

이것은 미래에 답이 될 수 있습니다 :) 브라우저가 곧 도착하기를 바랍니다 :) ♬
jave.web

1
나는 미래의 대답은 사용하는 것입니다 생각 프록시
제임스 롱

@JamesLong 네, 맞습니다! 미래가 도래 한 것으로 밝혀졌습니다. :) 질문을 한 지 3 년이 지난 지금 FF (그리고 곧 다른 브라우저에서도 작동합니다). 아래에 답변을 추가했습니다.
sandstrom

2

아직 아무도 삼항 연산자를 언급하지 않은 것에 놀랐습니다.

var emptyObj = {a:'123', b:'234', c:0};
var defaultValue = 'defaultValue';
var attr = 'someNonExistAttribute';
emptyObj.hasOwnProperty(attr) ? emptyObj[attr] : defaultValue;//=> 'defaultValue'


attr = 'c'; // => 'c'
emptyObj.hasOwnProperty(attr) ? emptyObj[attr] : defaultValue; // => 0

이렇게하면 'c'의 값이 0이더라도 올바른 값을 얻을 수 있습니다.


1
Object.withDefault = (defaultValue,o={}) => {
  return new Proxy(o, {
    get: (o, k) => (k in o) ? o[k] : defaultValue 
  });
}

o = Object.withDefault(42);
o.x  //=> 42

o.x = 10
o.x  //=> 10
o.xx //=> 42

그래서 ... 프록시를 사용한다는 것은 이제 모든 멋진 Object 메서드를 잃는다는 것을 의미합니다. :(
Meredith

0

이것은 실제로 Object.create. "정의되지 않은"속성에 대해서는 작동하지 않습니다. 그러나 기본값이 주어진 사람들에게는.

var defaults = {
    a: 'test1',
    b: 'test2'
};

그런 다음 속성 개체를 만들 때 Object.create

properties = Object.create(defaults);

이제 첫 번째 개체가 비어 있지만 프로토 타입이 defaults개체를 가리키는 두 개의 개체가 있습니다 . 테스트하려면 :

console.log('Unchanged', properties);
properties.a = 'updated';
console.log('Updated', properties);
console.log('Defaults', Object.getPrototypeOf(properties));


-1

헤더가 내 문제 설명과 일치하기 때문에 해결책을 찾고 왔지만 내가 찾던 것은 아니지만 내 문제에 대한 해결책을 얻었습니다 (날짜와 같은 동적 인 속성에 대한 기본값을 갖고 싶었습니다. ).

let Blog = {
title  : String,
image  : String,
body   : String,
created: {type: Date, default: Date.now}
}

위의 코드는 내가 마침내 해결 한 해결책이었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.