2013-07-07 2 views
-1

javascript에서 한 네임 스페이스의 내용을 다른 네임 스페이스의 내용으로 덤프하려고합니다. 여기자바 스크립트에서 네임 스페이스를 가져 오기 위해 eval을 사용합니다.

var CHESSMEN = { 

    Chariot: function(color) { 
    return { 
     color: color, 
     abbreviation: 'R', 
     type: 'Chariot' 
    }; 
    }, 

    Horse: function(color) { 
    return { 
     color: color, 
     abbreviation: 'H', 
     type: 'Horse' 
    }; 
    }, 

    Elephant: function(color) { 
    return { 
     color: color, 
     abbreviation: 'E', 
     type: 'Elephant' 
    }; 
    }, 

    Advisor: function(color) { 
    return { 
     color: color, 
     abbreviation: 'A', 
     type: 'Advisor' 
    }; 
    }, 

    General: function(color) { 
    return { 
     color: color, 
     abbreviation: 'G', 
     type: 'General' 
    }; 
    }, 

    Cannon: function(color) { 
    return { 
     color: color, 
     abbreviation: 'C', 
     type: 'Cannon' 
    }; 
    }, 

    Soldier: function(color) { 
    return { 
     color: color, 
     abbreviation: 'S', 
     type: 'Soldier' 
    }; 
    } 
} 
Object.freeze(CHESSMEN) 

function Game(board) { 

    for (var piece in CHESSMEN) { 
    eval('var ' + piece + ' = CHESSMEN.' + piece); 
    } 

    if (typeof(board) === 'undefined') { 
    var board = { 
     a1: new Chariot('red'), 
     b1: new Horse('red'), 
     c1: new Elephant('red'), 
     d1: new Advisor('red'), 
     e1: new General('red'), 
     f1: new Advisor('red'), 
     g1: new Elephant('red'), 
     h1: new Horse('red'), 
     i1: new Chariot('red'), 
     b3: new Cannon('red'), 
     h3: new Cannon('red'), 
     a4: new Soldier('red'), 
     c4: new Soldier('red'), 
     e4: new Soldier('red'), 
     g4: new Soldier('red'), 
     i4: new Soldier('red'), 
     a10: new Chariot('black'), 
     b10: new Horse('black'), 
     c10: new Elephant('black'), 
     d10: new Advisor('black'), 
     e10: new General('black'), 
     f10: new Advisor('black'), 
     g10: new Elephant('black'), 
     h10: new Horse('black'), 
     i10: new Chariot('black'), 
     b8: new Cannon('black'), 
     h8: new Cannon('black'), 
     a7: new Soldier('black'), 
     c7: new Soldier('black'), 
     e7: new Soldier('black'), 
     g7: new Soldier('black'), 
     i7: new Soldier('black') 
    }; 
    } 

    // et cetera 
} 

나는 냉동 개체의 키를 반복하는 for in 루프를 사용하고로 그 키와 관련된 값을 덤프 eval을 사용하고 다음과 같이 내가 직접이 일을 알아낼 수있는 유일한 방법입니다 Game 생성자의 범위입니다. 나는 많은 사람들이 eval을 사용하지 말라고 들었지만, 직접 네임 스페이스를 병합하는 다른 방법을 보지 못했습니다. 이게 안전하지 않니? CHESSMEN 객체의 속성으로 chessmen 생성자를 호출하는 것이 어떻게 든 좋을까요? Chariotnew를 사용하려고하는 경우에 당신이 그것을 가지고 방법을 구현하여

var board = { 
    a1: new CHESSMAN.Chariot('red'), 
    b1: new CHESSMAN.Horse('red'), 
    c1: new CHESSMAN.Elephant('red'), 
    //etc. 

또한, 당신은 거의 확실히하지 않을 : @zerkms 지적

+3

왜 * 가져 오기 *해야합니까? "CHESSMEN.Chariot"등으로 사용하지 않는 이유는 무엇입니까? – zerkms

+0

가져 오기에 _disadvantage_가 있는지 알고 싶습니다. 그러나 당신의 질문에 답하기 위해, 나는 'CHESSMEN.Chariot'보다'Chariot'을 사용할 충분한 이유가 없습니다. 나는이 공식이 안전하지 않은지에 대해서 궁금해한다. – HandyAndyShortStack

+2

예 - 당신은 작업 해결에 필요하지 않은 것을하고 있습니다. 귀하의 모든 단계는 어떤 요구 사항에 의해 야기됩니다. 반대로 - 당신이 이상한 것들을 할 때 "왜"아닌지로 정당화하십시오 - 사실이 아닙니다. – zerkms

답변

1

그것은 가능하지만, 많이 낙담하고 엄격 모드에서 불가능합니다.

with (CHESSMEN) { 
    // Now CHESSMEN's properties are available without saying "CHESSMEN.whatever" 
    console.log(Chariot === CHESSMEN.Chariot); // logs "true" 
} 

나는 반복 : 이것은 나쁜 생각입니다. 어떤 식별자가 무엇인지 언급하는 것이 더 어렵고, 느리게 실행될 수 있으며, 앞으로 호환되지 않습니다. 자세한 내용은 MDN을 참조하십시오.

eval의 안전성에 관해서 : 나중에 코드가 변경되어 CHESSMEN에 사용자 정의 속성이있을 수있는 경우 공격자가 코드를 끔찍한 악의적 인 행동을하게하는 foo; doHorriblyEvilThing();으로 지정할 수 있습니다 .

+0

감사합니다. 내 자바 스크립트에서 별도의 네임 스페이스를 유지하는 데 익숙해 져야한다고 생각합니다. 현재 보안 문제가 없더라도 앞으로 코드를 수정할 때 보안에 대해 항상 염려해야한다는 점에 특히 감사드립니다. – HandyAndyShortStack

+0

@HandyAndyShortStack : 무엇의 보안? 너 자신을 보호하고 있니? – zerkms

2

, 당신은 등 CHESSMEN.Chariot를 사용하여 접근해야 . 당신이 원하는 패턴은 다음과 같습니다 그렇지 않으면

Chariot: function(color) { 
    this.color = color; 
    this.abbreviation = 'R'; 
    this.type = 'Chariot' 
    }, 

, 당신은 당신이 아마 원하는이다 Chariot의 인스턴스에 반대 작성하는 객체 리터럴을 할 것이다 반환 무슨 new를 호출 할 때. 당신이 정말로 필요로하는 모든 당신이 반환하는 단지 값이있는 경우에, 당신은 new없이 코드를 작성할 수 있습니다 :

var board = { 
    a1: CHESSMAN.Chariot('red'), 
    b1: CHESSMAN.Horse('red'), 
    c1: CHESSMAN.Elephant('red'), 
    //etc. 
관련 문제