1

클로저 컴파일러로 소스를 컴파일하고 네트워크에서 이벤트 객체가있는 함수를 호출하면 애플리케이션에서 콘솔에 오류가 발생합니다. 라는클로저 컴파일러 externs 문제를 해결하지만 왜 이해하지 못했습니까?

기능은 다음과 같습니다

/** 
* @param {goog.events.Event} event Socket.io-Wrapper Event. 
*/ 
de.my.app.admin.prototype.onSaved = function(event){ 
    var category = event.data[0].category; //<-- here it throws the error because category get compiled. 
    var id  = event.data[0].id; 
    var oldid = event.data[0].oldid; 
[...] 
} 

이벤트 객체 내가 예상되는 동작은이

{ data:{ 
    0: { 
     category: 'someString', 
     id:  5, 
     oldid: -5 
    } } 
[...someMoreValuesAddedBySocketIO...] 
} 

것 같습니다.

는 지금은 파일 내 externs이 같은 externs 선언을 추가하지만 난 기능에서 @param의 유형 선언을 변경하지 않았고 오류가 사라 : 한마디로

var xterns; 
/** 
* @typedef {{ 
* category : string, 
* oldid : number, 
* id  : number 
* }} 
*/ 
xterns.NOTUSEDNAME; 

/** 
* @type {string} 
*/ 
xterns.NOTUSEDNAME.prototype.category; 

/** 
* @type {number} 
*/ 

xterns.NOTUSEDNAME.prototype.oldid; 

/** 
* @type {number} 
*/ 
xterns.NOTUSEDNAME.prototype.id; 

: 나는 @param {goog.events.Event} event 선언을 가지고 있고 xterns.NOTUSEDNAME에 대한 extern은 컴파일러 문제를 해결합니다 ... 왜 이런 일이 일어날 지 설명 할 수 있습니까?

답변

3

이것은 일반적인 오해입니다. extern 개체가 동일한 이름의 속성을 포함하면 클로저 컴파일러는 속성의 이름을 바꾸지 않습니다. FAQ을 참조하십시오. 유형 기반 최적화가 활성화 된 경우 더 이상 사실이 아니며 코드가 다시 손상 될 것으로 예상됩니다.

이 코드 유형이 안전하고 경고없이 컴파일, 당신도해야합니다 : 데이터 속성 구문 event.data[0]['category']을 인용하여

  1. 참조. JSON Data에서 자주 사용하는이 메서드를 사용하여 컴파일러에서 속성의 이름을 변경하지 않습니다.

  2. 데이터 개체를 강력한 형식의 배열로 정의하는 사용자 지정 개체로 goog.events.Event 형식을 확장하십시오.

예 :

/** 
* @constructor 
* @extends {goog.events.Event} 
*/ 
de.my.app.AdminEvent = function() {}; 
goog.inherits(de.my.app.AdminEvent, goog.events.Event); 

/** @type {Array.<{category:string, id:number, oldid:number}>} */ 
de.my.app.AdminEvent.prototype.data = []; 

는 당신의 정확한 상황에 따라, 인터페이스는 더 좋은 옵션이 될 수 있습니다.