_.each([1,2,3,4], n=> console.log(n))
_.each(null, n=> console.log(n))
list 가 null이면 프로그램이 멈춘다.
each는 다른 함수 반복문에 자주 쓰이는 중요한 함수다. null이 인자로 들어와도 그럴싸하게 동작할 방법이 필요하다.
함수형 프로그래밍은 불완전한 값이 들어와도 그럴싸한 값을 리턴해 전체 프로그램이 동작하게 하도록 프로그래밍하는 경향이 있다.
get
값을 안전하게 가져오는 함수
/* 요소 리스트 값을 하나씩 꺼내어 준다.*/
function each(list, iter){
for(let i=0;i<get(list,"length");i++){
iter(list[i]);
}
return list;
}
/*안전하게 값 가져오기*/
function get (obj,key){
return obj === null ? undefined : obj[key];
}
null을 만나면 undefined라는 그럴싸한 값을 반환해 프로그램이 멈추지 않게 한다.
get을 each에 적용했다.
_.each([1,2,3,4], n=> console.log(n))
_.each(null, n=> console.log(n))
console.log( _.filter(null, n=> true));
console.log( _.map(null, n=> n));
이제 프로그램이 안 멈춘다.
더불어 each를 사용한 모든 함수들이 혜택을 받게 됐다.
추가개선, keys, is_object
each가 돌림직한 데이터도 순회를 했으면 좋겠다.
우선 보조함수가 필요
/* 객체의 keys를 안전하게 리턴하는 함수*/
function keys(obj){
return is_object(obj) ? Object.keys(obj) : [];
}
/* 객체인지 안전하게 확인하는 함수 */
function is_object(obj){
return typeof obj === "object" && !!obj;
}
!!obj 의미
_.each({a:1,b:2,c:3}, a=>console.log(a))
//기대하는 동작 => 1 , 2, 3 출력
/* 요소 리스트 값을 하나씩 꺼내어 준다.*/
function each(list, iter){
const _keys = keys(list);
for(let i=0;i<_keys.length;i++){
iter(list[_keys[i]]);
}
return list;
}
_.each({a:1,b:2,c:3}, a=>console.log(a));
_.each([1,2,3], a=>console.log(a));
이제 object도 순회할 수 있게 됐다.
원리는 object의 key들을 배열로 만들어 key를 순회할 수 있도록 만든다.
자바스크립트는 친절하게도 object 속성 접근방식과 array 인덱스 접근 방식이 동일하다.
object[key] , array[index]
배열의 경우 추상화해서 생각하면 배열 요소의 key는 인덱스로 볼 수 있다.
배열의 인덱스를 key로 하는 key 배열이 생성된다.
이 유연한 동작이 가능한 것은 Object.keys() 동작방식과 배열과 오브젝트를 같은 방식으로 접근할 수 있는 자바스크립트 특징 덕분이다.
불필요한 관심사를 제거하고, 돌림직한 데이터를 마치 같은 자료구조처럼 다룰 수 있게 됐다.
좀 더 알아보기 Object.keys()
열거할만한 데이터를 keys()함수에 이자로 들어올 수 있다.
//Object.keys 동작방식
console.log(Object.keys(["a","b","c"]).join("-") );
console.log(Object.keys("가나다라").join("-") );
console.log(Object.keys({고:"바",구:"바",마:"나"}).join("-") );
//Object.values 동일
console.log(Object.values(["a","b","c"]).join("-") );
console.log(Object.values("가나다라").join("-") );
console.log(Object.values({고:"바",구:"바",마:"나"}).join("-") );
문자열을 결국 char 배열이므로 똑같이 돌림직한 데이터다.
for...in , for ... of
//Object.keys 는 for...in 과 유사
function forIn(list){
const result = [];
for(const arg in list) result.push(arg);
return result.join("-");
}
//Object.values 는 for...of 과 유사
function forOf(list){
const result = [];
for(const arg of list) result.push(arg);
return result.join("-");
}
console.log(forIn(["a","b","c"]) );
console.log(forIn("가나다라") );
console.log(forIn({고:"바",구:"바",마:"나"}));
console.log(forOf(["a","b","c"]) );
console.log(forOf("가나다라") );
console.log(forOf({고:"바",구:"바",마:"나"}));//불가능
단일 접근 원칙
동일한 접근 방식에 관련된 법칙,
데이터 접근에 불필요한 관심사를 제거하고 동일한 방식으로 다룬다.
//단일 접근 원칙
class Data{
constructor(name, age){
this._name = name;
this._age =age;
}
get name(){
console.log("name 게터 호출");
return this._name;
}
get age(){
console.log("age 게터 호출");
return this._age;
}
set name(arg){
console.log("name 세터 호출");
this._name = arg;
}
set age(arg){
console.log("age 세터 호출");
this._age = arg;
}
}
const data1 = new Data("홍길동", 50);
console.log(data1.name); //변수처럼 다룬다
data1.name = "임꺽정"
console.log(data1.name); //변수처럼 다룬다
'개발 > 함수형 프로그래밍' 카테고리의 다른 글
08 - 컬렉션 중심 프로그래밍 - filter(거르기) (0) | 2023.06.18 |
---|---|
07 - 컬렉션 중심 프로그래밍 - map (수집하기) (0) | 2023.06.17 |
05 - 파이프라인, pipe, go (1) | 2023.06.14 |
04 - map, filter에 curryr 적용, reduce (0) | 2023.06.12 |
03 - 커링, curry, curryr (0) | 2023.06.11 |