본문 바로가기
Javascript

predicate, forEach, Map, filter, Class, getter/setter 에 대해 알아보기

by Antonio Bae 2023. 7. 18.

 

 

1.predicate 

함수형 인터페이스란? 

1개의 추상 메소드를 갖는 인터페이스 디폴트 메소드는 많이 존재할 수 있다. 

자바의 람다 표현식은 함수형 인터페이스로만 사용 가능

 

함수형 인터페이스 예제

predicate interface는 T에대한 조건에 대해서 true / false를 반환하는 Functional Interface

Predicat<T>로 사용되고 여기서 T는 파라미터이자 조건이다. T가 true 또는 false를 return하도록 작성하면 된다.

https://poiemaweb.com/js-array-higher-order-function

 

코드예제

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Predicate</title>
</head>
<body>
<script>
//데이터의 값이 조건을 만족하는지 검사한다는 의미
//argument를 받아 boolean 값을 반환하는 함수형 인터페이스
//정석적인 코드는 아님

function makeCounter(predicate) {
let num = 0;
return function() {
num=predicate(num);
return num;
};
}
function increase(n) {
return ++n;
}

function decrease(n) {
return --n;
}

const increaser = makeCounter(increase);
console.log(increaser()); //1
console.log(increaser()); //2

const decreaser = makeCounter(decrease);
console.log(decreaser()); //-1
console.log(decreaser()); //-2
</script>
</body>
</html>

2.forEach

https://poiemaweb.com/js-array-higher-order-function

 

Higher order function | PoiemaWeb

배열(array)는 1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용한다. 자바스크립트의 배열은 객체이며 유용한 내장 메소드를 포함하고 있다.

poiemaweb.com

forEach 메소드는 for 문 대신 사용할 수 있다. 

배열을 순회하며 배열의 각 요소에 대하여 인자로 주어진 콜백함수를 실행한다. 

반환값은 undefined이다. 콜백 함수의 매개변수를 통해 배열 요소의 값, 요소 인덱스, forEach 메소드를 호출한 배열, 즉 this를 전달 받을 수 있다. 

forEach 메소드는 원본 배열(this)을 변경하지 않는다. 

하지만 콜백 함수는 원본 배열(this)을 변경할 수는 있다. 

forEach 메소드는 for 문과는 달리 break 문을 사용할 수 없다. 

다시 말해, 배열의 모든 요소를 순회하며 중간에 순회를 중단할 수 없다. 

forEach 메소드는 for 문에 비해 성능이 좋지는 않다. 하지만 for 문보다 가독성이 좋으므로 적극 사용을 권장한다.

<script>
const fruits = ['Banana', 'Orange', 'Apple'];
// ascending(오름차순)
fruits.sort();
console.log(fruits); // [ 'Apple', 'Banana', 'Orange' ]
// descending(내림차순)
fruits.reverse();
console.log(fruits); // [ 'Orange', 'Banana', 'Apple' ]

const points = [40, 100, 1, 5, 2, 25, 10];
points.sort();
console.log(points); // [ 1, 10, 100, 2, 25, 40, 5 ]

const num = [40, 100, 1, 5, 2, 25, 10];

// 숫자 배열 오름차순 정렬
// 비교 함수의 반환값이 0보다 작은 경우, a를 우선하여 정렬한다.
num.sort(function (a, b) { return a - b; });
// ES6 화살표 함수
// points.sort((a, b) => a - b);
console.log(num); // [ 1, 2, 5, 10, 25, 40, 100 ]

// 숫자 배열에서 최소값 취득
console.log(num[0]); // 1

// 숫자 배열 내림차순 정렬
// 비교 함수의 반환값이 0보다 큰 경우, b를 우선하여 정렬한다.
num.sort(function (a, b) { return b - a; });
// ES6 화살표 함수
// points.sort((a, b) => b - a);
console.log(num); // [ 100, 40, 25, 10, 5, 2, 1 ]

// 숫자 배열에서 최대값 취득
console.log(num[0]); // 100

//문자열
const category = ['a','e','c','y','d']
category.sort();
console.log(category);


//forEach
const numbers = [2,4,6];
pows = [];
numbers.forEach(function(item) {
pows.push(item**2);
});
console.log(pows);

let total = 0;
numbers.forEach(function(item,index,self) {
console.log(`numbers[${index}]=${item}`);
total+=item;
});
console.log(total);

//selfIndex
numbers.forEach(function(item,index,self){
self[index] = Math.pow(item,2);
});
console.log(numbers);

//forEach 메소드는 모든 요소를 탐색하는 메소드라 중간에 탈출할 방법이 없음, break 사용 불가
 
</script>

 

 

3.Map

배열을 순회하며 각 요소에 대하여 인자로 주어진 콜백 함수의 반환값(결과값)으로 새로운 배열을 생성하여 반환한다. 

이때 원본 배열은 변경되지 않는다.

forEach 메소드는 배열을 순회하며 요소 값을 참조하여 무언가를 하기 위한 함수이며 map 메소드는 배열을 순회하며 요소 값을 다른 값으로 맵핑하기 위한 함수이다.

https://poiemaweb.com/js-array-higher-order-function

 

Higher order function | PoiemaWeb

배열(array)는 1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용한다. 자바스크립트의 배열은 객체이며 유용한 내장 메소드를 포함하고 있다.

poiemaweb.com

<script>
//map 메소드는 배열을 순회하며 요소 값을 다른 값으로 맵핑하기 위한 함수
//Math.sqrt
//배열을 순회하며 각 요소에 대하여 인자로 주어진 콜백 함수의 반환값(결과값)으로 새로운 배열을 생성하여 반환한다. 이때 원본 배열은 변경되지 않는다.
const numbers = [2, 4, 6];

const roots = numbers.map(function (item) {
// 반환값이 새로운 배열의 요소가 된다. 반환값이 없으면 새로운 배열은 비어 있다.
return Math.sqrt(item);
//제곱근한 결과를 roots로 반환한다
});
console.log(roots);
console.log(numbers);

</script>

4.filter

filter 메소드를 사용하면 if 문을 대체할 수 있다.

배열을 순회하며 각 요소에 대하여 인자로 주어진 콜백함수의 실행 결과가 true인 배열 요소의 값만을 추출한 새로운 배열을 반환

배열에서 특정 케이스만 필터링 조건으로 추출하여 새로운 배열을 만들고 싶을 때 사용한다.이때 원본 배열은 변경되지 않는다.

콜백 함수의 매개변수를 통해 배열 요소의 값, 요소 인덱스, filter 메소드를 호출한 배열, 즉 this를 전달 받을 수 있다.

https://poiemaweb.com/js-array-higher-order-function

 

Higher order function | PoiemaWeb

배열(array)는 1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용한다. 자바스크립트의 배열은 객체이며 유용한 내장 메소드를 포함하고 있다.

poiemaweb.com

<script>
 

const result = [1, 2, 3, 4, 5].filter(function (item, index, self) {
console.log(`[${index}] = ${item}`);
return item % 2;
});

console.log(result);

// 영어 점수 임의의 값 중 80점 이상인 카운트가 몇개인지 filter를 활용하여 작성하시오
let Grade = [];
while(Grade.length <20){
let number = parseInt(Math.random()*100)+1;
if(Grade.indexOf(number) < 0){
Grade.push(number);
}
}
document.write("영어점수:"+Grade+"<br>");

let over80 = [];
over80 = Grade.filter((v,i,a) => {
return v>=80;
});
document.write(`80점이상 총 ${over80.length}명 입니다.`+"<br>");

 

5.Class

객체 지향(Object oriented) 프로그래밍이란?

# 우리가 실생활에서 쓰는 모든 것을 객체라 하며, 객체 지향 프로그래밍은 프로그램 구현에 필요한 객체를 파악하고 각각의 객체들의 역할이 무엇인지를 정의하여 객체들 간의 상호작용을 통해 프로그램을 만드는 것

 

새로운 버전 ---------------설계도: 속성과 메서드로 구분해서 구분해내는 능력이 다

속성과 메서드를 올바르게 설정하여 올바르게 꺼내오는 방법 설계하는가가 매우 중요!!

 

constructor:생성자

https://poiemaweb.com/es6-class

 

Class | PoiemaWeb

자바스크립트는 프로토타입 기반(prototype-based) 객체지향형 언어다. 비록 다른 객체지향 언어들과의 차이점에 대한 논쟁들이 있긴 하지만, 자바스크립트는 강력한 객체지향 프로그래밍 능력들을

poiemaweb.com

객체 지향 프로그래밍 특징

객체 지향 프로그래밍의 특징 객체 지향 프로그래밍은 크게 추상화 , 캡슐화 , 상속 , 다형성 의 네가지 특징을 가짐

 

getter /setter

사용이유: 객체의 무결성을 보장하기 위해 사용

장점:getter와 setter를 사용하여 속성을 노출하면서도 속성의 내부 표현을 숨길 수 있다.

 

무결성이란 무엇인가요? 데이터의 정확성과 일관성을 유지하고 보증하는 것

 

Getter, Setter를 이용해서 데이터를 생성 및 접근을 하게 되면 들어오는 값을 바로 저장하는 게 아닌, 한번 검증하고 처리할 수 있도록 할 수 있기 때문에 데이터의 무결성이 지켜집니다.

 

Getter : 본 필드의 값을 숨긴 채 내부에서 가공된 값을 꺼낼 수 있다. 

Setter : 필드를 private로 만들어 외부의 접근을 제한한 후, Setter를 사용해 전달받은 값을 내부에서 가공해 필드에 넣어줄 수 있다.

 

예시1. 쿠팡 상품 리스트 만들기

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Coupang_obj</title>
<style>
*{margin:0; padding:0;}
.mainBox{

}
.bigBox{
width:100px; height: 100px;
border: 3px solid gray;
display: inline-block; float: left;
background-size: cover;
background-position: 50% 50%;
}
.smallBox{
width:50px; height: 50px;
border: 1px solid salmon;
display: inline-block; float: left;
background-size: cover;
background-position: 50% 50%;
}
</style>
</head>
<body>
<div id="mainBox" class="mainBox">
<!-- <div class="bigBox"></div>
<div class="smallBox"></div> -->
</div>
<script>
//식별자
// :::::: new 칠때 생성
//박스사이즈 2종 - css로 제어 bigBox / smallBox
// :::::: 속성에 편성 ===> getter / setter 구성
// 지금 박스는 뭐니가 필요없으므로 setter만 필요
//이미지 지정- 속성편성 얘도 setter만 필요.
//박스 출력-위치: #mainBox
//메소드 편성 ==> 일반 메소드(Public Method)
class OriginBox{
constructor(idV, boxKind, urlInfo) { //idV 매개변수를 받으며 boxKind, urlInfo 초기화
this.idV = idV;
this.boxKind = boxKind == "newBox" ? "bigBox":"smallBox";
this.urlInfo = urlInfo;
}
set setBoxKind(boxId) {
this.boxKind = boxId == "newBox" ? "bigBox":"smallBox";
//setBoxKind 세터는 boxId 매개변수의 값을 기반으로 boxKind 속성을 설정
//new 박스면 bigBox, 아니면 smallBox 출력
}
set setUrlPath(urlPath) {//setUrlPath 세터는 제공된 urlPath로 urlInfo 속성을 설정
this.urlInfo = urlPath;
}
showBox() { //showBox 메서드는 상자를 표시하기 위해 정의됨
// `<div id="ZARD" class="bigBox">Test</div>`
document.getElementById('mainBox').innerHTML +=`<div id="${this.idV}" class="${this.boxKind}">Test1</div>`;
//지정된 idV와 boxKind로 <div> 요소를 생성하고 "mainBox" 컨테이너에 추가
document.getElementById(this.idV).style.backgroundImage = `url(${this.urlInfo})`;
//urlInfo 속성을 사용하여 상자의 배경 이미지를 설정
}
}
let zardBox = new OriginBox("ZARD","newBox","https://dw3nkyfm845lb.cloudfront.net/story/003/1773/thumbnail_1.jpg");
// 클래스 정의 외부에서 "ZARD"라는 id를 가진 OriginBox 인스턴스인 zardBox가 생성
// zardBox.setBoxKind = "newBox";
// zardBox.setBoxKind = "smallBox";
// zardBox.setBoxKind = "bigBox";
zardBox.showBox();
</script>
</body>
</html>

 

예시2 이미지 나열 리스트 만들기

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Class</title>
</head>
<body>
<script>
// 객체 : 1.속성(생성에 필요한 속성-constructor/내가 갖고있는 일반 속성)
// 2.메서드-일반 메소드 / getter(속성 관련=property) / setter(속성 관련=property)
// getter: 값을 불러오는 것 setter: 그 값을
//Getter는 객체의 속성(property) 값을 반환하는 메서드이며, Setter는 객체의 속성 값을 설정, 변경하는 메서드, 정보 은닉용, 안정성, 유지보수성 높일 수 있음
//내 속성을 밖에 건드리지 못하게 하기 위함
//static 정적변수(지역변수) 다른 멤버 변수처럼 클래스 내부에 선언

var Person = (function () {
//Constructor
function Person(name) {
this._name = name;//생성자 함수는 name 매개변수를 받고, _name이라는 속성을 초기화
}
//public method
Person.prototype.sayHi = function () { //sayHi라는 메서드가 있구나 정도만 알면 됨
console.log('Hi!' + this._name); // 이 메서드는 HI와 _name을 출력
};

//return constructor(생성자)
return Person;
}());
//me가 인스턴스
var me = new Person('Lee'); //me라는 인스턴스를 생성하고 sayHi 메서드를 호출하여 Hi! Lee출력
me.sayHi(); //Hi! Lee.

console.log(me instanceof Person); //me라는 인스턴스가 Person 생성자 함수의 인스턴스가 맞니? ->true

// 새로운 버전 ---------------설계도: 속성과 메서드로 구분해서 구분해내는 능력이 다
// 속성과 메서드를 올바르게 설정하여 올바르게 꺼내오는 방법 설계하는가가 매우 중요!!
class Person1 {
constructor(name1) {
this._name1 = name1; //name1이라는 속성을 생성자로 초기화 식별자!! constructor
}
sayHi() { //일반 public 메서드
console.log(`Hi! ${this._name1}`);
}
}

const me1 = new Person1('Bae'); //Person1 클래스로 me1이라는 인스턴스를 생성하고
me1.sayHi(); // sayHI메서드 호출하여 Hi!Bae 출력
console.log(me1 instanceof Person1); //Person1에서 파생되는 me1이라는 인스턴스가 맞니?

// 클래스 선언문
class Person3 {
// constructor(생성자). 이름을 바꿀 수 없다.
constructor(name3) {
// this는 클래스가 생성할 인스턴스를 가리킨다.
// _name 이라는 클래스 필드를 초기화
this._name3 = name3;
}
}
// me3 인스턴스 생성하고 생성자에 전달된 값으로 _name3 속성이 초기화
const me3 = new Person3('Lee');
console.log(me3); // Person {_name: "Lee"}

class Foo {
constructor(arr = []) { //Foo라는 클래스를 정의 생성자는 arr 매개변수를 받고, _arr이라는 속성 초기화
this._arr = arr;
}

// getter: get 키워드 뒤에 오는 메소드 이름 firstElem은 클래스 필드 이름처럼 사용된다.
get firstElem() {
// getter는 반드시 무언가를 반환해야 한다.
return this._arr.length ? this._arr[0] : null;
//이 메서드는 _arr 배열의 첫 번째 요소를 반환
}
}

const foo = new Foo([1, 2]);
// Foo 클래스로 foo 인스턴스를 생성하고
// 필드 firstElem에 접근하면 getter가 호출된다.
console.log(foo.firstElem); // 1

//setter:클래스 필드에 값을 할당할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용
//할당 시에 메소드가 호출됨
class Foo2 {
constructor(arr = []) {
this._arr = arr;
}
// getter: get 키워드 뒤에 오는 메소드 이름 firstElem은 클래스 필드 이름처럼 사용된다.
get firstElem() {
// getter는 반드시 무언가를 반환하여야 한다.
return this._arr.length ? this._arr[0] : null;
}
// setter: set 키워드 뒤에 오는 메소드 이름 firstElem은 클래스 필드 이름처럼 사용된다.
set firstElem(elem) {
// ...this._arr은 this._arr를 개별 요소로 분리한다
this._arr = [elem, ...this._arr]
}
}
const foo2 = new Foo2([1, 2]);
// 클래스 필드 lastElem에 값을 할당하면 setter가 호출됨
foo2.firstElem = 100;//foo2의 firstElem이라는 속성의 매개변수에 값이 있을 건데 그 값으로 100을 할당하여 setter 메서드 호출.
console.log(foo2.firstElem); // 그 후, getter 메서드를 호출하여 반환된 값이 첫번째 요소 100출력
</script>
</body>

</html>