const Style = (_=>{ ... })();
이러한 형태의 내용에 대해 궁금이 생겼다.
let Style = (_=>{ return 10 })();
typeof(Style) //"number"
let Style = (_=>{ return 10 });
typeof(Style) //"function"
첫번째 것은 괄호로 묶은 함수 자체를 실행하는 것이 Style이므로 실행 결과의 리턴값인 10인 number가 typeof(Style)이 되고
두번째 것은 괄호로 묶은 함수 자체가 Style이므로 함수를 선언한 typeof(Style)이 function이 된다.
let Style = (_=>{ return class {} });
Style //_=>{ return class {} }
let Style = (_=>{ return class {} })();
Style //class {}
첫번째 Style은 안에있는 함수 자체를 의미하고
두번째 Style을 그것을 실행후 리턴한 class{} 자체를 의미한다.
const Style = ((_) => {
const prop = new Map, prefix = 'webkt,moz,ms,chrome,o,khtml'.split(',');
const NONE = Symbol();
const BASE = document.body.style;
const getKey = (key) => {
if(prop.has(key)) return prop.get(key);
if(key in BASE) prop.set(key, key);
else if(!prefix.some(v =>{
// prefix를 붙인 속성은 존재하는가?를 알아볼 차례
// 메소드 some의 인수인 callback 함수 부분이다.
// webkitBackground 이런식으로 속성명 첫글자가 대문자이므로 표준 key인 background의 앞에 vendor prefix를 붙이고 대문자로 바꾸고 나머지 뒤인 'ackground'를 붙여주는 작업이 필요하다.
const newKey = v + key[0].toUpperCase() + key.substr(1);
if(newKey in BASE){ // prefix붙인 속성이 body에 있다면,
prop.set(key, newKey); // border-radius 부르면 prefix를 붙인 진짜 이름을 캐시에 저장
key = newKey; // 리턴할 key는 더이상 원래 키가 아니라 newKey
return true; // 진짜 이름을 찾았으니 여기서 끊어 라는것. some을 더 돌지 않아도 된다고 끊어버리는 것이다.
} else return false;
})){
// some의 결과가 false일 경우에만 여기에 들어온다.
prop.set(key, NONE);
key = NONE;
}
return key; // 그냥 key가 리턴되든지, newKey가 리턴되든지, NONE이 리턴될 것임
}; // end of getKey()
return class {
constructor(style) {
this._style = style;
} // 생성자에 style객체를 준다. 이 클래스는 style 객체를 안고 태어난다.
// 키를 얻기(스타일 시트에 있는 background라는 값을 얻고싶다면?)
get(key) {
key = getKey(key); // 반드시 getKey에 보내서 진짜 이름을 얻어야 한다.
if (key === NONE) return null; // 브라우저가 지원하지 않는 경우 부드럽게 null을 리턴하기 // Unsupported Property 문제 해결!
return this._style[key]; // 이름이 있다면 진짜 이름으로 style객체에 해당 속성값을 가져오자
}
set(key, val) {
key = getKey(key);
// key가 NONE이 아니면
if (key !== NONE) this._style[key] = val; // 값을 설정
// NONE이면 스타일을 아예 건들지 않는다(Graceful Fail)
return this; // set을 계속 호출하는 경우가 많아서 set을 쓸 수 있게 this를 리턴
}
};
})();
이는 간단히
const Style = ((_)=>{ ... return Class{ ... }})();
즉, Style은 리턴한 Class 자체를 의미하는 것이다.
const prop = new Map, prefix = 'webkt,moz,ms,chrome,o,khtml'.split(',');
const NONE = Symbol();
const BASE = document.body.style;
const getKey = (key) => {
if(prop.has(key)) return prop.get(key);
if(key in BASE) prop.set(key, key);
else if(!prefix.some(v =>{
const newKey = v + key[0].toUpperCase() + key.substr(1);
if(newKey in BASE){
prop.set(key, newKey);
key = newKey;
return true;
} else return false;
})){
prop.set(key, NONE);
key = NONE;
}
return key;
};
class Style {
constructor(style) {
this._style = style;
} // 생성자에 style객체를 준다. 이 클래스는 style 객체를 안고 태어난다.
// 키를 얻기(스타일 시트에 있는 background라는 값을 얻고싶다면?)
get(key) {
key = getKey(key); // 반드시 getKey에 보내서 진짜 이름을 얻어야 한다.
if (key === NONE) return null; // 브라우저가 지원하지 않는 경우 부드럽게 null을 리턴하기 // Unsupported Property 문제 해결!
return this._style[key]; // 이름이 있다면 진짜 이름으로 style객체에 해당 속성값을 가져오자
}
set(key, val) {
key = getKey(key);
// key가 NONE이 아니면
if (key !== NONE) this._style[key] = val; // 값을 설정
// NONE이면 스타일을 아예 건들지 않는다(Graceful Fail)
return this; // set을 계속 호출하는 경우가 많아서 set을 쓸 수 있게 this를 리턴
}
};
사실 이렇게 분리해도 문제는 없다.
그러나 두 차이는 내가 생각할 때, 전역변수로 해당 값들을 뺄 필요성은 없고 해당 Style이 실행되어 만들어질때만 사용하는게 효율적이므로 저렇게 사용하지 않았을까싶다.