<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>noob-d.log</title>
        <link>https://velog.io/</link>
        <description>나의 기록</description>
        <lastBuildDate>Thu, 22 Dec 2022 08:21:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. noob-d.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/noob-d" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[프로그래머스 징검다리]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%95%EA%B2%80%EB%8B%A4%EB%A6%AC</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%95%EA%B2%80%EB%8B%A4%EB%A6%AC</guid>
            <pubDate>Thu, 22 Dec 2022 08:21:34 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
출발지점부터 distance만큼 떨어진 곳에 도착지점이 있습니다. 그리고 그사이에는 바위들이 놓여있습니다. 바위 중 몇 개를 제거하려고 합니다.
예를 들어, 도착지점이 25만큼 떨어져 있고, 바위가 [2, 14, 11, 21, 17] 지점에 놓여있을 때 바위 2개를 제거하면 출발지점, 도착지점, 바위 간의 거리가 아래와 같습니다.</p>
<p><img src="https://velog.velcdn.com/images/noob-d/post/92c1d758-d8d3-48d3-ae30-a8ffacfaa498/image.png" alt=""></p>
<p>위에서 구한 거리의 최솟값 중에 가장 큰 값은 4입니다.</p>
<p>출발지점부터 도착지점까지의 거리 distance, 바위들이 있는 위치를 담은 배열 rocks, 제거할 바위의 수 n이 매개변수로 주어질 때, 바위를 n개 제거한 뒤 각 지점 사이의 거리의 최솟값 중에 가장 큰 값을 return 하도록 solution 함수를 작성해주세요.</p>
<p><strong>제한사항</strong></p>
<ul>
<li>도착지점까지의 거리 distance는 1 이상 1,000,000,000 이하입니다.</li>
<li>바위는 1개 이상 50,000개 이하가 있습니다.</li>
<li>n 은 1 이상 바위의 개수 이하입니다.</li>
</ul>
<p><strong>입출력 예</strong></p>
<p><img src="https://velog.velcdn.com/images/noob-d/post/2f4fa003-9ca2-408e-8ba1-177a23d94c6a/image.png" alt=""></p>
<pre><code>function solution(distance, rocks, n) {
    var answer = 0;
    let arr =[0,...rocks.sort((a,b) =&gt; a-b),distance]

    let search = (function(){
        let x = 0
        let y = arr[arr.length-1]

        while(x &lt;= y){
            let num = Math.floor((x + y)/2);
            let sum = 0
            let now = 0

            for(let i = 1;i &lt; arr.length; i++){
                if((arr[i] - now) &lt; num){
                    sum += 1
                }else{
                    now = arr[i];
                }
            }

            if(sum &gt; n){
                y = num - 1
            }
            else
            {
                x = num + 1
            }
        }
        answer = y
    }())

    search

    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로토타입]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85</guid>
            <pubDate>Thu, 22 Dec 2022 08:21:26 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트는 명령형, 함수형, 프로토타입 기반, 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어다. 자바스크립트를 이루고 있는것중 원시값을 빼면 다 객체로 이뤄져 있다.</p>
<h2 id="객체지향-프로그래밍">객체지향 프로그래밍</h2>
<p>객체의 집합으로 프로그램을 표현하는 프로그래밍 패러다임을 말한다.
실세계의 실체를 인식하는 철학적 사고를 프로그래밍에 접목하려는 시도로 시작되었고 <strong>실체는 특징이나 성질을 나타내는 속성을 가지고 인식하거나 구별 할 수 있다</strong>.
실체에는 많은 속성이 있지만 그 중에서 원하는 속성만 참조하고 싶을때 필요한 속성만 간추려 표현한것을 추상화라고 한다.</p>
<pre><code>let sum = {
    num : 0,
    getPlay() {
        return this.num += 1
    }
}
console.log(sum.num) // 0
console.log(sum.getPlay()) // 1
console.log(sum.num) // 1</code></pre><p>sum이란 객체안에 num은 상태를 나타내는 데이터이고 프로퍼티라 한다.
sum.getPlay() 은 num에 1을 더해주는 동작이라 하고 메서드라 한다.
객체 지향 프로그래밍은 객체의 상태를 나타내는 데이터와 상태 데이터를 조작할 수 있는 동작을 하나의 논리적인 단위로 묶은 복합적인 자료구조다. </p>
<h2 id="상속과-프로토타입">상속과 프로토타입</h2>
<p>객체의 프로퍼티 또는 메서드를 다른 객체가 상속 받아 그대로 사용 할 수 있는걸 말한다.
자바스크립트는 <strong>프로토타입을 기반으로 상속하여 기존의 코드를 재사용</strong>한다.</p>
<pre><code>function Circle(radius){
    this.radius = radius
    this.getDiameter = function(){
        return 2 * this.radius
    }
}
const circle1 = new Circle(5)
const circle2 = new Circle(2)
// 생성자 함수를 이용해 동일한 동작하는 getDiameter 메서드를 중복 생성하고 모든 인스턴스가 중복 소유한다.</code></pre><p>예제대로면 Circle 생성자 함수가 생성하는 모든 객체는 radius프로퍼티와 getDiameter메서드를 갖는다.
동일한 메서드가 중복 소유되어 메모리를 불필요하게 낭비하게 된다.
프로토타입을 기반으로 상속해서 해결 할 수 있다.</p>
<pre><code>// 생성자 함수
function sum(num){
    this.num = num
}
// sum 생성자 함수의 인스턴스가 메서드를 공유해서 사용 할 수 있도록 프로토 타입에 추가됨
// sum 생성자 함수의 prototype 프로퍼티에 바인딩 됨. 
// sum의 인스턴스는 부모 객체인 sum.prototype으로부터 메서드를 상속받는다
sum.prototype.getArea = function () {
    return this.num + 1
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[무지의 먹방 라이브]]></title>
            <link>https://velog.io/@noob-d/%EB%AC%B4%EC%A7%80%EC%9D%98-%EB%A8%B9%EB%B0%A9-%EB%9D%BC%EC%9D%B4%EB%B8%8C</link>
            <guid>https://velog.io/@noob-d/%EB%AC%B4%EC%A7%80%EC%9D%98-%EB%A8%B9%EB%B0%A9-%EB%9D%BC%EC%9D%B4%EB%B8%8C</guid>
            <pubDate>Thu, 22 Dec 2022 08:21:21 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong></p>
<p>평소 식욕이 왕성한 무지는 자신의 재능을 뽐내고 싶어 졌고 고민 끝에 카카오 TV 라이브로 방송을 하기로 마음먹었다.</p>
<p>그냥 먹방을 하면 다른 방송과 차별성이 없기 때문에 무지는 아래와 같이 독특한 방식을 생각해냈다.</p>
<p>회전판에 먹어야 할 N 개의 음식이 있다.
각 음식에는 1부터 N 까지 번호가 붙어있으며, 각 음식을 섭취하는데 일정 시간이 소요된다.
무지는 다음과 같은 방법으로 음식을 섭취한다.</p>
<ul>
<li>무지는 1번 음식부터 먹기 시작하며, 회전판은 번호가 증가하는 순서대로 음식을 무지 앞으로 가져다 놓는다.</li>
<li>마지막 번호의 음식을 섭취한 후에는 회전판에 의해 다시 1번 음식이 무지 앞으로 온다.</li>
<li>무지는 음식 하나를 1초 동안 섭취한 후 남은 음식은 그대로 두고, 다음 음식을 섭취한다.</li>
<li><ul>
<li>다음 음식이란, 아직 남은 음식 중 다음으로 섭취해야 할 가장 가까운 번호의 음식을 말한다.</li>
</ul>
</li>
<li>회전판이 다음 음식을 무지 앞으로 가져오는데 걸리는 시간은 없다고 가정한다.</li>
</ul>
<p>무지가 먹방을 시작한 지 K 초 후에 네트워크 장애로 인해 방송이 잠시 중단되었다.
무지는 네트워크 정상화 후 다시 방송을 이어갈 때, 몇 번 음식부터 섭취해야 하는지를 알고자 한다.
각 음식을 모두 먹는데 필요한 시간이 담겨있는 배열 food_times, 네트워크 장애가 발생한 시간 K 초가 매개변수로 주어질 때 몇 번 음식부터 다시 섭취하면 되는지 return 하도록 solution 함수를 완성하라.</p>
<p><strong>제한사항</strong></p>
<p>food_times 는 각 음식을 모두 먹는데 필요한 시간이 음식의 번호 순서대로 들어있는 배열이다.
k 는 방송이 중단된 시간을 나타낸다.
만약 더 섭취해야 할 음식이 없다면 -1을 반환하면 된다.</p>
<p><strong>정확성 테스트 제한 사항</strong></p>
<p>food_times 의 길이는 1 이상 2,000 이하이다.
food_times 의 원소는 1 이상 1,000 이하의 자연수이다.
k는 1 이상 2,000,000 이하의 자연수이다.</p>
<p><strong>효율성 테스트 제한 사항</strong></p>
<p>food_times 의 길이는 1 이상 200,000 이하이다.
food_times 의 원소는 1 이상 100,000,000 이하의 자연수이다.
k는 1 이상 2 x 10^13 이하의 자연수이다.</p>
<p><strong>입출력 예</strong>
<img src="https://velog.velcdn.com/images/noob-d/post/2f4c37d1-2478-490f-ae8b-c311171d4f07/image.png" alt=""></p>
<p>아직 다 못품;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 자동완성]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1</guid>
            <pubDate>Thu, 22 Dec 2022 08:21:16 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong></p>
<p>포털 다음에서 검색어 자동완성 기능을 넣고 싶은 라이언은 한 번 입력된 문자열을 학습해서 다음 입력 때 활용하고 싶어 졌다. 예를 들어, go 가 한 번 입력되었다면, 다음 사용자는 g 만 입력해도 go를 추천해주므로 o를 입력할 필요가 없어진다! 단, 학습에 사용된 단어들 중 앞부분이 같은 경우에는 어쩔 수 없이 다른 문자가 나올 때까지 입력을 해야 한다.
효과가 얼마나 좋을지 알고 싶은 라이언은 학습된 단어들을 찾을 때 몇 글자를 입력해야 하는지 궁금해졌다.</p>
<p>예를 들어, 학습된 단어들이 아래와 같을 때</p>
<p>go
gone
guild</p>
<ul>
<li>go를 찾을 때 go를 모두 입력해야 한다.</li>
<li>gone을 찾을 때 gon 까지 입력해야 한다. (gon이 입력되기 전까지는 go 인지 gone인지 확신할 수 없다.)</li>
<li>guild를 찾을 때는 gu 까지만 입력하면 guild가 완성된다.
이 경우 총 입력해야 할 문자의 수는 7이다.</li>
</ul>
<p>라이언을 도와 위와 같이 문자열이 입력으로 주어지면 학습을 시킨 후, 학습된 단어들을 순서대로 찾을 때 몇 개의 문자를 입력하면 되는지 계산하는 프로그램을 만들어보자.</p>
<p><strong>입력 형식</strong>
학습과 검색에 사용될 중복 없는 단어 N개가 주어진다.
모든 단어는 알파벳 소문자로 구성되며 단어의 수 N과 단어들의 길이의 총합 L의 범위는 다음과 같다.</p>
<p>2 &lt;= N &lt;= 100,000
2 &lt;= L &lt;= 1,000,000</p>
<p><strong>출력 형식</strong>
단어를 찾을 때 입력해야 할 총 문자수를 리턴한다.</p>
<p><strong>입출력 예제</strong>
<img src="https://velog.velcdn.com/images/noob-d/post/7b104ae3-cf7a-44a0-b6e3-993de29ca93a/image.png" alt=""></p>
<pre><code>function solution(words) {
    var answer = 0;
    let obj = {}

    words.forEach(word =&gt; {
        let currObj = obj
        for(let i = 0; i &lt; word.length; i++){
            if(currObj[word[i]]){
                currObj[word[i]][0] += 1
            } 
            else 
            {
                currObj[word[i]] = [1, {}]
            }
            currObj = currObj[word[i]][1]
        }
    })
    words.forEach(word =&gt; {
        let currObj = obj
        for(let i = 0; i &lt; word.length; i++){
            answer++

            if(currObj[word[i]][0]===1){
                break;
            } 
            currObj = currObj[word[i]][1]
        }
    })
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 풍선 터트리기]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%92%8D%EC%84%A0-%ED%84%B0%ED%8A%B8%EB%A6%AC%EA%B8%B0</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%92%8D%EC%84%A0-%ED%84%B0%ED%8A%B8%EB%A6%AC%EA%B8%B0</guid>
            <pubDate>Thu, 22 Dec 2022 08:21:11 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
일렬로 나열된 n개의 풍선이 있습니다. 모든 풍선에는 서로 다른 숫자가 써져 있습니다. 당신은 다음 과정을 반복하면서 풍선들을 단 1개만 남을 때까지 계속 터트리려고 합니다.</p>
<p>임의의 인접한 두 풍선을 고른 뒤, 두 풍선 중 하나를 터트립니다.
터진 풍선으로 인해 풍선들 사이에 빈 공간이 생겼다면, 빈 공간이 없도록 풍선들을 중앙으로 밀착시킵니다.
여기서 조건이 있습니다. 인접한 두 풍선 중에서 번호가 더 작은 풍선을 터트리는 행위는 최대 1번만 할 수 있습니다. 즉, 어떤 시점에서 인접한 두 풍선 중 번호가 더 작은 풍선을 터트렸다면, 그 이후에는 인접한 두 풍선을 고른 뒤 번호가 더 큰 풍선만을 터트릴 수 있습니다.</p>
<p>당신은 어떤 풍선이 최후까지 남을 수 있는지 알아보고 싶습니다. 위에 서술된 조건대로 풍선을 터트리다 보면, 어떤 풍선은 최후까지 남을 수도 있지만, 어떤 풍선은 무슨 수를 쓰더라도 마지막까지 남기는 것이 불가능할 수도 있습니다.</p>
<p>일렬로 나열된 풍선들의 번호가 담긴 배열 a가 주어집니다. 위에 서술된 규칙대로 풍선들을 1개만 남을 때까지 터트렸을 때 최후까지 남기는 것이 가능한 풍선들의 개수를 return 하도록 solution 함수를 완성해주세요.</p>
<p><strong>제한 사항</strong>
a의 길이는 1 이상 1,000,000 이하입니다.
a[i]는 i+1 번째 풍선에 써진 숫자를 의미합니다.
a의 모든 수는 -1,000,000,000 이상 1,000,000,000 이하인 정수입니다.
a의 모든 수는 서로 다릅니다.</p>
<p><strong>입출력 예</strong>
<img src="https://velog.velcdn.com/images/noob-d/post/35b4f884-7465-4c2b-a462-37b3d2fc8226/image.png" alt=""></p>
<pre><code>function solution(a) {
    var answer = 0;
    let len = a.length
    let left = new Array(len);
    let right = new Array(len);

    left[0] = a[0]
    right[len - 1] = a[len - 1]
    for(let i = 1 ; i &lt; a.length; i++){
        if(a[i] &gt; left[i-1]){
            left[i] = left[i-1]
        }
        else
        {
            left[i] = a[i]
        }
    }
    for(let i=len-2 ; i&gt;=0 ; i--){
        if(right[i+1] &lt; a[i]){
            right[i] = right[i+1]
        }
        else
        {
            right[i] = a[i]
        }
    }

    for(let i=1 ; i&lt;len-1 ; i++){
        if(left[i-1] &lt; a[i] &amp;&amp; a[i] &gt; right[i+1]){
            continue;
        }
        answer++;
    }
    answer += 2
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 베스트앨범]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94</guid>
            <pubDate>Thu, 22 Dec 2022 08:21:07 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다.</p>
<p>속한 노래가 많이 재생된 장르를 먼저 수록합니다.
장르 내에서 많이 재생된 노래를 먼저 수록합니다.
장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.
노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.</p>
<p><strong>제한사항</strong>
genres[i]는 고유번호가 i인 노래의 장르입니다.
plays[i]는 고유번호가 i인 노래가 재생된 횟수입니다.
genres와 plays의 길이는 같으며, 이는 1 이상 10,000 이하입니다.
장르 종류는 100개 미만입니다.
장르에 속한 곡이 하나라면, 하나의 곡만 선택합니다.
모든 장르는 재생된 횟수가 다릅니다.
<strong>입출력 예</strong>
<img src="https://velog.velcdn.com/images/noob-d/post/6ca07c1d-6bf7-4a60-b018-4bd8f5d24ca6/image.png" alt=""></p>
<pre><code>function solution(genres, plays) {
    var answer = [];
    let x = new Map();
    let arr = [];

    for(let i = 0; i &lt; genres.length; i++){
        let f = x.get(genres[i]);
        if(f === undefined){
            f = [0, []]
        }

        f[0] = f[0] + plays[i];
        f[1].push([plays[i], i]);
        x.set(genres[i], f);
    }
    arrX = [...x]
    arrX.sort((a,b) =&gt; b[1][0] - a[1][0])

    for(let i = 0; i &lt; arrX.length; i++){
        arrX[i][1][1].sort((a,b) =&gt; {
            if(a[0] === b[0]){
                return a[1]-b[1]
            }
            else 
            {
                return b[0]-a[0]
            }
        })
    }
   for(i of arrX){
       let num = 0;
       for(w of i[1][1]){
           if(num === 2){
               break
           }
           answer.push(w[1]);
           num++;
       }       
    }
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[일급 객체]]></title>
            <link>https://velog.io/@noob-d/%EC%9D%BC%EA%B8%89-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@noob-d/%EC%9D%BC%EA%B8%89-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Thu, 22 Dec 2022 08:21:01 GMT</pubDate>
            <description><![CDATA[<h2 id="일급-객체">일급 객체</h2>
<ul>
<li>무명의 리터럴로 생성 할 수 있다. 런타임에 생성이 가능하다</li>
<li>변수나 자료구조에 저장할 수 있다</li>
<li>함수의 매개변수에 전달할 수 있다</li>
<li>함수의 반환값으로 사용할 수 있다</li>
</ul>
<p>함수가 일급 객체라는것은 함수를 객체와 동일하게 사용 가능하다는 뜻이다. 객체는 값이고 함수도 값과 동일하게 취급 가능하다.</p>
<h2 id="함수-객체의-프로퍼티">함수 객체의 프로퍼티</h2>
<p>함수의 프로퍼티 어트리뷰트를 확인해 보자.</p>
<pre><code>function x(y) {
    return y * y
}
console.log(Object.getOwnPropertyDescriptors(x))
// {length: {…}, name: {…}, arguments: {…}, caller: {…}, prototype: {…}}

arguments
: 
{value: null, writable: false, enumerable: false, configurable: false}

caller
: 
{value: null, writable: false, enumerable: false, configurable: false}

length
: 
{value: 1, writable: false, enumerable: false, configurable: true}

name
: 
{value: &#39;x&#39;, writable: false, enumerable: false, configurable: true}

prototype
: 
{value: {…}, writable: true, enumerable: false, configurable: false}
[[Prototype]]
: 
Object
</code></pre><p>arguments,caller,length,name,prototype 프로퍼티는 일반 객체에는 없는 함수 객체 고유의 프로퍼티다.
하지만 <strong><strong>proto</strong></strong>는 접근자 프로퍼티며 함수 객체 고유의 프로퍼티가 아니라 Object.prototype 객체의 프로퍼티를 상속받은걸 확인할 수 있다.</p>
<h3 id="arguments-프로퍼티">arguments 프로퍼티</h3>
<p>함수 호출 시 전달된 인수들의 정보를 담고있는 순회 가능한 유사 배열 객체며 함수 내부에서 지역 변수처럼 사용된다. 함수 외부에선 사용 불가.</p>
<pre><code>function sum (x,y){
    console.log(arguments)
    return x + y
}

console.log(sum())             // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(sum(1,2))        // Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(sum(1,2,3))        // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

// arguments.length도 먹히므로 매개변수 갯수를 확정 할 수 없는 가변 인자 함수 구현할때 쓸 수 있음
// for(let i = 0 ; i &lt; arguments.length; i++) 반복문 활용 가능</code></pre><blockquote>
<p>Symbol.iterator???
arguments 객체를 순회 가능한 자료구조인 이터러블로 만들기 위한 프로퍼티다.</p>
</blockquote>
<pre><code>function multiply(x, y){
    const iterato = arguments[Symbol.iterator]()
    console.log(iterator.next())    // {value: 1, done: false}
    console.log(iterator.next())    // {value: 2, done: false}
    console.log(iterator.next())    // {value: undefined, done: true}
    return x * y
}
multiply(1,2)</code></pre><p>함수를 호출할 때 전달하는 인수가 불명확하고 인수 개수를 확인하고 그에 따라 함수의 동작을 다시 정의해야할때 arguments 객체가 쓰인다.</p>
<p>arguments 객체는 배열 형태로 인자 정보를 담고 있지만 유사 배열 객체다. 따라서 배열 메서드를 사용하지 못한다. Function.prototype.call, Faunction.prototype.apply를 사용해 간접 호출해야 한다.</p>
<pre><code>// 함수에 매개 변수가 없다
function sum (){
    let arr = Array.prototype.slice.call(arguments)
    // 배열을 reduce 메소드를 이용하여 순회하며 즉시 실행 함수로 인자를 전부 더해준다.
    return arr.reduce(function (pre, cur) {
        return pre + cur
    },0)
}
console.log(sum(1,2,3)) // 6


// Rest 파라미터로 쉽게 구현도 가능하다
function sum (...arr) {
    return arr
} 
console.log(sum(1,2,3)) // [1, 2, 3]</code></pre><h3 id="length-프로퍼티">length 프로퍼티</h3>
<p>함수 객체의 length 프로퍼티는 함수를 정의할 때 선언한 매개변수의 개수를 가리킴.</p>
<pre><code>// Rest 파라미터
function sum (...arr) {
    return arr
} 
console.log(sum(1,2,3)) // [1, 2, 3]    인수로 숫자 1,2,3를 넣음
sum.length    // 0 Rest 파라미터는 개수로 안침

// 매개변수 배열
function sum (arr) {
    return arr
} 
console.log(sum([1,2,3]))    // 배열을 집어 넣음
sum.length    //    1 배열은 자체를 인자 하나로 침</code></pre><p>arguments 객체의 length와 다른점은 arguments는 <strong>인자의 개수</strong>를 가르키고
함수 객체의 length 프로퍼티는 <strong>매개변수의 개수</strong>를 가르킨다.</p>
<h3 id="name-프로퍼티">name 프로퍼티</h3>
<p>name 프로퍼티는 함수 이름을 가르킨다. <strong>함수를 호출할때 쓰는건 식별자로 호출하는 것이고 함수 이름은 다른거다</strong>.</p>
<pre><code>// inden이라는 식별자에 함수이름 fun을 할당했다.
let inden = function fun() {}
console.log(inden.name) // fun  함수 이름을 리턴
console.log(fun.name) // fun is not defined 함수 이름으로 호출이 불가능하다</code></pre><p>보통의 함수 선언문과 익명 함수 표현식은 식별자와 함수이름이 같다.</p>
<h3 id="proto-접근자-프로퍼티"><strong><strong>proto</strong></strong> 접근자 프로퍼티</h3>
<p>객체는 [Prototype]의 내부 슬롯을 갖는다. <strong><strong>proto</strong></strong>는 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용되는 <strong>접근자 프로퍼티</strong>다. </p>
<pre><code>const obj = {x : 1, y : 2}
console.log(obj.__proto__ === Object.prototype) // true
console.log(obj.hasOwnProperty(&#39;y&#39;)) // true</code></pre><p>hasOwnProperty메서드는 인수로 전달받은게 객체 고유의 프로퍼티 키일 경우에만 true 상속 받은 프로퍼티인 경우 false를 반환한다.</p>
<h3 id="prototype-프로퍼티">prototype 프로퍼티</h3>
<p>생성자 함수로 호출할 수 있는 함수 객체인 일반 함수와 생성자 함수가 소유하는 프로퍼티다.
일반 객체와 생성자 함수로 호출 불가능한 non-constructor에는 prototype 프로퍼티가 없다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[생성자 함수에 의한 객체 생성]]></title>
            <link>https://velog.io/@noob-d/%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98%EC%97%90-%EC%9D%98%ED%95%9C-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@noob-d/%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98%EC%97%90-%EC%9D%98%ED%95%9C-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1</guid>
            <pubDate>Thu, 22 Dec 2022 08:20:52 GMT</pubDate>
            <description><![CDATA[<h2 id="object-생성자-함수">Object 생성자 함수</h2>
<p>new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하여 반환한다.</p>
<pre><code>const obj = new Object()
obj.hi = &quot;hello&quot;
console.log(obj.hi) // hello</code></pre><p>String, Number,Boolean,Function,Array,Date,RegExp,promise 등의 빌트인 생성자 함수도 제공한다.</p>
<p>객체를 생성할때 객체 리터럴에 의해 생성하면 보기편하고 간단하다. 하지만 동일한 프로퍼티를 갖는 객체를 여러개 생성해야 할때는 비효율 적이다.</p>
<pre><code>function Circle(radius){
// 생성자 함수 내부의 this는 생성할 인스턴스를 가리킨다
    this.radius = radius
    this.getDiameter = function(){
        return 2 * this.radius
    }
}
const circle1 = new Circle(5)
circle1 // Circle {radius: 5, getDiameter: ƒ} this로 객체의 키와 값이 만들어 졌다.</code></pre><blockquote>
<p>this??
this는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수다.
일반함수로서 호출하면 전역 객체
메서드로서 호출하면 메서드를 호출한 객체
생성자 함수로서의 호출은 생성자 함수가 생성할 인스턴스</p>
</blockquote>
<h3 id="인스턴스-생성">인스턴스 생성</h3>
<p>new 연산자와 함께 생성자 함수를 호출하면 암묵적으로 빈 객체를 생성한다 이 객체가 인스턴스다.
그리고 이 인스턴스는 this에 바인딩된다. 이 과정은 함수 코드의 런타임 이전에 실행된다.</p>
<blockquote>
<p>바인딩??
식별자와 값을 연결하는 과정을 의미한다. 예로 변수선언은 식별자와 메모리 공간의 주소를 바인딩 하는거다.</p>
</blockquote>
<h3 id="인스턴스-초기화">인스턴스 초기화</h3>
<p>함수 내 코드가 한줄씩 실행되어 this에 바인딩된 인스턴스를 초기화 한다. this에 바인딩 되어 있는 인스턴스에 프로퍼티나 메서드를 추가하고 인수로 전달받은 초기값을 할당하여 초기화 하거나 고정값을 할당한다.</p>
<h3 id="인스턴스-반환">인스턴스 반환</h3>
<p>생성자 함수 내부의 런타임이 끝나면 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환된다.
단. return 문에 명시한 객체가 있다면 그 객체가 반환된다, 원시값을 return 문에 명시했다면 그 원시 값은 무시된다.</p>
<pre><code>function Circle(radius){
    this.radius = radius
    this.getDiameter = function(){
        return 2 * this.radius
    }
    // 객체를 명시적으로 반환했다.
    return {}
}
const circle1 = new Circle(5)
circle1    // {} this가 반환되지 못한다

function Circle(radius){
    this.radius = radius
    this.getDiameter = function(){
        return 2 * this.radius
    }
    // 원시값를 명시적으로 반환했다.
    return 100
}
const circle1 = new Circle(5)
circle1    // Circle {radius: 5, getDiameter: ƒ} 원시값을 명시적으로 반환했으나 무시됐다.</code></pre><h2 id="callconstruct">[[Call]],[[Construct]]</h2>
<p>함수는 객체다. 하지만 일반 객체와는 다르게 호출 할 수 있다.
그래서 일반 객체가 갖고 있는 내부 슬롯과 내부 메서드, 함수 객체만을 위한 내부 슬롯인 [Environment] [FormalParameters] 내부 메서드 [Call] [Construct]를 가지고 있다.</p>
<p>함수를 일반 함수로써 호출하면 함수 객체의 내부 메서드[Call] 이 호출되고.
new 연산자로 생성자 함수로써 호출하면 [Construct] 가 호출된다.</p>
<p>내부 메서드 [Call]을 갖는 함수를 callable, 
[Construct]를 갖는 함수 객체를 constructor,
[Construct]를 갖지 않는 함수 객체를 non-constructor 이라 부른다.</p>
<p>함수 객체는 내부 메서드 [Call]을 갖고 있으므로 호출 할 수 있다.
하지만 모든 함수 객체가 [Construct]를 가지고 있는건 아니다.</p>
<h2 id="new-연산자">new 연산자</h2>
<p>new 연산자와 함께 함수를 호출하면 생성자 함수로 동작한다. [Call]이 아닌[Construct]가 호출된다.
위에서 다루듯이 객체를 반환하지 않고 원시값을 반환하는 함수는 반환문이 무시되어 빈 객체를 생성한다.</p>
<p>객체를 반환하는 일반 함수는 함수가 생성한 객체를 반환한다.
생성자 함수를 일반적인 함수로서 호출하게 되면 함수 내부의 this가 전역 객체 window가 되니 주의한다.
생성자 함수는 첫 문자를 대문자로 기술한다.</p>
<h3 id="newtarget">new.target</h3>
<p>생성자 함수가 new 연산자 없이 호출되면 this가 전역 객체가 된다고 했다. 이를 막기 위해 new.target을 지원한다.</p>
<pre><code>function Circle(radius){
    // 생성자 함수를 new연산자로 호출하는지 확인하는 조건문, 그렇지 않으면 재귀해서 new 연산자로써 호출 시킨다.
    if(!new.target){
        return new Circle(radius)
    }
    this.radius = radius
    this.getDiameter = function(){
        return 2 * this.radius
    }
    return 100
}
// 생성자 함수를 new 연산자 없이 호출했다
const circle1 = Circle(5)
circle1 // Circle {radius: 5, getDiameter: ƒ} 정상적으로 호출됐다.</code></pre><blockquote>
<p>스코프 세이프 생성자 패턴??</p>
</blockquote>
<pre><code>function Circle(radius){
    // 생성자 함수를 new연산자로 호출하는지 확인하는 조건문, 그렇지 않으면 재귀해서 new 연산자로써 호출 시킨다.
    if(!(this instanceof Circle)){
        return new Circle(radius)
    }
    this.radius = radius
    this.getDiameter = function(){
        return 2 * this.radius
    }
    return 100
}
// 생성자 함수를 new 연산자 없이 호출했다
const circle1 = Circle(5)
circle1 // Circle {radius: 5, getDiameter: ƒ} 정상적으로 호출됐다.</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로퍼티 어트리뷰트]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0-%EC%96%B4%ED%8A%B8%EB%A6%AC%EB%B7%B0%ED%8A%B8</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0-%EC%96%B4%ED%8A%B8%EB%A6%AC%EB%B7%B0%ED%8A%B8</guid>
            <pubDate>Thu, 22 Dec 2022 08:20:44 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.
프로퍼티 어트리뷰트는 자바스크립트 엔진이 관리하는 내부 상태 값인 내부 슬롯 [[Value]],[[Writable]],[[Enumerable]],[[Configurable]]이다. 프로퍼티 어트리뷰트에 직접 접근은 불가능하나 Object.getOwnPropertyDescriptor 메서드를 사용하여 확인 가능하다.</p>
<pre><code>var o, d;

o = { get foo() { return 17; } };
d = Object.getOwnPropertyDescriptor(o, &#39;foo&#39;);
// d는 { configurable: true, enumerable: true, get: /* getter 함수 */, set: undefined }
// mdn 예제</code></pre><p>Object.getOwnPropertyDescriptor메서드를 호출 할 때 첫 번째 매개 변수에는 객체의 참조를 전달하고 두번째 매개변수에는 프로퍼티 키를 문자열로 전달한다. 그럼 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다. 상속받은 프로퍼티나 존재하지 않는 프로퍼티를 요구하면 undefined를 반환한다.</p>
<p>value
속성과 관련된 값 (데이터 설명자만).</p>
<p>writable
속성과 관련된 값이 변경될 수 있는 경우에만 true (데이터 설명자만).</p>
<p>get
속성에 대해 getter로서 제공하는 함수 또는 getter가 없는 경우 undefined (접근자 설명자만).</p>
<p>set
속성에 대해 setter로서 제공하는 함수 또는 setter가 없는 경우 undefined (접근자 설명자만).</p>
<p>configurable
이 속성 설명자의 유형이 바뀔 수 있는 경우에만 그리고 속성이 해당 객체에서 삭제될 수 있는 경우 true.</p>
<p>enumerable
이 속성이 해당 객체의 속성 열거 중에 나타나는 경우에만 true.</p>
<h2 id="내부-슬롯과-내부-메서드">내부 슬롯과 내부 메서드</h2>
<p>자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티와 의사 메서드다. 실제로 자바스크립트 엔진에서 동작하지만 개발자가 접근하게 공개한 객체의 프로퍼티는 아니다.
일부 내부 슬롯과 내부 메서드는 간접적으로 접근할 수단은 있다.
예를들어 객체는[[Prototype]]라는 내부 슬롯을 갖는데 직접 접근은 불가능하나 <strong>proto</strong> 간접 접근은 가능하다.</p>
<pre><code>const test = {
    x : 1
}
test.__proto__        // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}</code></pre><h2 id="데이터-프로퍼티와-접근자-프로퍼티">데이터 프로퍼티와 접근자 프로퍼티</h2>
<p>프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분한다</p>
<ul>
<li>데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티다.</li>
<li>접근자 프로퍼티 : 자체적으로는 값을 갖지 않지만 다른 데이터 프로퍼티를 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티다.</li>
</ul>
<h3 id="데이터-프로퍼티">데이터 프로퍼티</h3>
<p>프로퍼티 어트리뷰트
<strong>value</strong></p>
<ul>
<li>프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값</li>
<li>값을 변경하면 [[Value]]에 값을 재할당한다. 프로퍼티가 없으면 생성하고 값을 [[Value]]에 저장한다.</li>
</ul>
<p><strong>writable</strong></p>
<ul>
<li>프로퍼티 값의 변경 가능 여부를 불리언 값으로 나타냄</li>
<li>[[Value]]값의 변경이 불가능 할 시 [[Writable]]는 false의 값을 가진다</li>
</ul>
<p><strong>configurable</strong></p>
<ul>
<li>프로퍼티 재정의 가능 여부를 불리언 값으로 나타냄</li>
<li>[[configurable]]가 false인 경우 프로퍼티의 삭제 , 프로퍼티 어트리뷰트 값의 변경이 금지된다. 단  [[Writable]]가 true일 시 [[Value]]의 변경과 [[Writable]]의 변경은 허용된다.</li>
</ul>
<p><strong>enumerable</strong></p>
<ul>
<li>프로퍼티의 열거 가능 여부를 불리언 값으로 나타냄</li>
<li>[[Enumerable]]의 값이 false인경우 해당 프로퍼티는 for...in문이나 object.keys 메서드 등으로 열거 할 수 없다.</li>
</ul>
<h3 id="접근자-프로퍼티">접근자 프로퍼티</h3>
<p>접근자 프로퍼티는 자체적으로는 값을 가지지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장 할 때 사용하는 접근자 함수로 구성된 프로퍼티다.
<strong>get</strong></p>
<ul>
<li>접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수, 접근자 프로퍼티 키로 프로퍼티 값에 접근하면 프로퍼티 어트리뷰트 [[Get]]의 값 <strong>gether</strong> 함수가 호출되고 그 결과가 프로퍼티 값으로 반환된다. </li>
</ul>
<p><strong>set</strong></p>
<ul>
<li>접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수. 접근자 프로퍼티 키로 프로퍼티 값을 저장하면 프로퍼티 어트리뷰트 [[Set]]의 값 <strong>setter</strong> 함수가 호출되고 그 결과가 프로퍼티 값으로 저장됨</li>
</ul>
<p><strong>enumerable</strong></p>
<ul>
<li>프로퍼티의 열거 가능 여부를 불리언 값으로 나타냄</li>
<li>[[Enumerable]]의 값이 false인경우 해당 프로퍼티는 for...in문이나 object.keys 메서드 등으로 열거 할 수 없다.</li>
</ul>
<p><strong>configurable</strong></p>
<ul>
<li>프로퍼티 재정의 가능 여부를 불리언 값으로 나타냄</li>
<li>[[configurable]]가 false인 경우 프로퍼티의 삭제 , 프로퍼티 어트리뷰트 값의 변경이 금지된다. 단  [[Writable]]가 true일 시 [[Value]]의 변경과 [[Writable]]의 변경은 허용된다.</li>
</ul>
<pre><code>const person = {
    // 데이터 프로퍼티
    firstName : &quot;first&quot;,
    lastName : &quot;name&quot;,

    // 접근자 프로퍼티
    // getter 함수 데이터 프로퍼티의 값을 읽을 때 호출하는 접근자 함수
    get fullName() {
        return `${this.firstName} ${this.lastName}`
    },
    // setter 함수 데이터 프로퍼티의 값을 저장할 때 호출하는 접근자 함수
    set fullName(name) {

        [this.firstName, this.lastName] = name.split(&#39; &#39;);
    }
}
// 데이터 프로퍼티 값의 참조
console.log(person.fistName + &#39; &#39; + person.lastName)    // first name

// 접근자 함수 set을 이용한 프로퍼티 값의 저장
person.fullName = &#39;second name&#39;
// 접근자 함수 get을 이용한 프로퍼티 값의 참조
console.log(person.fullName)    // second name

// 어트리뷰트를 확인하는법
// 데이터 프로퍼티의 어트리뷰트 확인 [Value] [Writable] [configurable] [Enumerable]
let descriptor = Object.getOwnPropertyDescriptor(person, &quot;firstName&quot;)

console.log(descriptor) 
// {value: &#39;second&#39;, writable: true, enumerable: true, configurable: true}

// 접근자 프로퍼티의 어트리뷰트 확인 [get] [set] [configurable] [Enumerable]
descriptor = Object.getOwnPropertyDescriptor(person, &quot;fullName&quot;)

console.log(descriptor)
// {enumerable: true, configurable: true, get: ƒ, set: ƒ}</code></pre><blockquote>
<p>프로토타입??
객체의 상위 객체의 역화를 하는 객체다. 자식 객체에게 자신의 프로퍼티와 메서드를 상속한다.
프로토 타입 체인은 프로토 타입이 단방향 링크드 리스트 형태로 연결되어 있는 상속 구조다. 객체에 접근하려는 프로퍼티나 메서드가 없으면 프로토타입 체인을 따라 프로퍼티나 메서드를 차례로 검색하게 된다.</p>
</blockquote>
<h2 id="프로퍼티의-정의">프로퍼티의 정의</h2>
<p>프로퍼티를 추가하며 어트리뷰트를 정의하거나 기존의 프로퍼티의 어트리뷰트를 재정의 하는걸 말한다. </p>
<ul>
<li>프로퍼티값을 갱신 가능 여부</li>
<li>프로퍼티 열거 가능 여부</li>
<li>프로퍼티 재정의 가능 여부 등<pre><code>const x = {};
// 데이터 프로퍼티의 정의
Object.defineProperty(x, &quot;first&quot;, {
  value : &quot;1&quot;,
  writable: true,
  enumerable: true,
  configurable: true
});
// writable 등의 어트리뷰트를 정의하지 않았다. 디폴트 값은 뭘까?
Object.defineProperty(x, &quot;second&quot;, {
  value : &quot;2&quot;
});
</code></pre></li>
</ul>
<p>// 프로퍼티 어트리뷰트 확인
let descripor = Object.getOwnPropertyDescriptor(x , &quot;first&quot;)
console.log(descripor)
// {value: &#39;1&#39;, writable: true, enumerable: true, configurable: true}</p>
<p>// 프로퍼티 어트리뷰트 확인
descripor = Object.getOwnPropertyDescriptor(x , &quot;second&quot;)
console.log(descripor)
// {value: &#39;2&#39;, writable: false, enumerable: false, configurable: false}
// 어트리뷰트를 정의하지 않으면 기본값은 false다.</p>
<pre><code>
Object.defineProperties 메서드를 활용하여 여러개의 프로퍼티를 한번에 정의 할 수 있다.
</code></pre><p>const x = {};</p>
<p>Object.defineProperties(x, {
// first scond 데이터 프로퍼티 정의
    first : {
        value : &quot;1&quot;,
        writable: true,
        enumerable: true,
        configurable: true
    },
    scond : {
        value : &quot;2&quot;,
        writable: true,
        enumerable: true,
        configurable: true
    },
    // 접근자 프로퍼티 정의
    sum: {
        get() {
            return <code>${this.first}+${this.scond}</code>
        },
        set(y) {
            [this.first, this.scond] = y.split(&#39;+&#39;)
        },
        enumerable : true,
        configurable : true
    }
});
// 접근자 프로퍼티 sum 동작확인
x.sum = &#39;3+4&#39;
console.log(x) // {first: &#39;3&#39;, scond: &#39;4&#39;}</p>
<pre><code>
## 객체 변경 방지
객체는 변경 가능하므로 프로퍼티를 추가하거나 삭제 가능하다.
메서드를 활용하여 어트리뷰트를 정의해 객체의 변경을 금지할 수 있다.
</code></pre><pre><code>                        추가    삭제    읽기    쓰기    어트리뷰트 재정의                  </code></pre><p>Object.preventExtensions     X           O         O           O              O<br>Object.seal                    X           X         O           O              X<br>Object.freeze                X           X         O           X              X     </p>
<pre><code>### Object.preventExtensions
객체의 확장을 금지한다는 뜻이고 프로퍼티의 추가를 금지한다.</code></pre><p>const x = {y: &quot;1&quot;}
// Object.isExtensible로 확장 가능한 객체 여부 확인 가능
console.log(Object.isExtensible(x))    //    true
// 객체 확장 금지
Object.preventExtensions(x)
console.log(Object.isExtensible(x))    // false
// 객체 확장 금지가 달려도 삭제는 가능하다
delete x.y
console.log(x) // {}</p>
<pre><code>
### Object.seal    
객체 밀봉이며 프로퍼치 추가 , 삭체 , 프로퍼티 어트리뷰트 재정의가 금지된다. 읽기와 쓰기만 가능하다.</code></pre><p>const x = {y: &quot;1&quot;}
// Object.isSealed로 밀봉된 객체여부 확인 가능
console.log(Object.isSealed(x))    // false</p>
<p>// 객체 밀봉
Object.seal(x)</p>
<p>// 프로퍼티 추가
x.w = &quot;2&quot; // 무시됨</p>
<p>// 프로퍼티 삭제
delete x.y    // 무시됨</p>
<p>// 프로퍼티 값 갱신은 가능
x.y = &quot;3&quot; 
console.log(x) // {y: &#39;1&#39;}</p>
<pre><code>
### Object.freeze
객체 동결이며 프로퍼티 추가, 삭제, 어트리뷰트 재정의 금지, 프로퍼티 값 갱신까지 금지된다. 동결된 객체는 읽기만 가능하다.</code></pre><p>const x = {y: &quot;1&quot;}
// Object.isFrozen로 동결된 객체여부 확인 가능 
console.log(Object.isFrozen(x))    // false</p>
<p>// 객체 동결
Object.freeze(x)</p>
<p>// 프로퍼티 추가
x.w = &quot;2&quot; // 무시됨</p>
<p>// 프로퍼티 삭제
delete x.y    // 무시됨</p>
<p>// 프로퍼티 값 갱신
x.y = &quot;3&quot; // 무시됨</p>
<pre><code>### 불변 객체
앞에 객체 확장, 밀봉, 동결은 직속 프로퍼티만 변경이 방지되는 얕은 변경 방지다. 즉 중첩된 객체에는 영향을 주지 못한다.
객체의 중첩 객체까지 동결하여 변경이 불가능한 읽기 전용의 불변 객체를 구현하려면 재귀적으로 Object.freeze 메서드를 호출해야한다.</code></pre><p>function deepFreeze(x) {
// 매개변수가 객체가 맞는지 확인 후 동결되지 않은 객체일때 작동하는 조건문
    if(x &amp;&amp; typeof x === &#39;object&#39; &amp;&amp; !Object.isFrozen(x)){
        //  객체를 동결한다
        Object.freeze(x);
        /* 
            객체내 중첩된 객체를 찾기위해 재귀한다
            Object.keys는 객체의 키를 배열로 반환한다.
            forEach는 배열을 순회하며 콜백 함수를 실행한다.
            Object.keys(x) = [name, address].forEach(y =&gt; deepFreeze(x[y]))
            -&gt; deepFreeze(person.name) -&gt; deepFreeze(person.address)
        */
        Object.keys(x).forEach(y =&gt; deepFreeze(x[y]))
    }
    return target
}
const person = {
    name : &quot;1&quot;,
    address: { city: &quot;seoul&quot;}
}
deepFreeze(person)
console.log(Object.isFrozen(person.address))    // true</p>
<p>```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 숫자 게임]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EA%B2%8C%EC%9E%84</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EA%B2%8C%EC%9E%84</guid>
            <pubDate>Tue, 25 Oct 2022 21:22:44 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
xx 회사의 2xN명의 사원들은 N명씩 두 팀으로 나눠 숫자 게임을 하려고 합니다. 두 개의 팀을 각각 A팀과 B팀이라고 하겠습니다. 숫자 게임의 규칙은 다음과 같습니다.</p>
<p>먼저 모든 사원이 무작위로 자연수를 하나씩 부여받습니다.
각 사원은 딱 한 번씩 경기를 합니다.
각 경기당 A팀에서 한 사원이, B팀에서 한 사원이 나와 서로의 수를 공개합니다. 그때 숫자가 큰 쪽이 승리하게 되고, 승리한 사원이 속한 팀은 승점을 1점 얻게 됩니다.
만약 숫자가 같다면 누구도 승점을 얻지 않습니다.
전체 사원들은 우선 무작위로 자연수를 하나씩 부여받았습니다. 그다음 A팀은 빠르게 출전순서를 정했고 자신들의 출전 순서를 B팀에게 공개해버렸습니다. B팀은 그것을 보고 자신들의 최종 승점을 가장 높이는 방법으로 팀원들의 출전 순서를 정했습니다. 이때의 B팀이 얻는 승점을 구해주세요.
A 팀원들이 부여받은 수가 출전 순서대로 나열되어있는 배열 A와 i번째 원소가 B팀의 i번 팀원이 부여받은 수를 의미하는 배열 B가 주어질 때, B 팀원들이 얻을 수 있는 최대 승점을 return 하도록 solution 함수를 완성해주세요.</p>
<p><strong>제한사항</strong>
A와 B의 길이는 같습니다.
A와 B의 길이는 1 이상 100,000 이하입니다.
A와 B의 각 원소는 1 이상 1,000,000,000 이하의 자연수입니다.
<strong>입출력 예</strong>
<img src="https://velog.velcdn.com/images/noob-d/post/5c5310a3-c125-413b-84ff-ef396dff0f89/image.png" alt="">
<img src="https://velog.velcdn.com/images/noob-d/post/c1a8c6c7-3e21-422c-beaa-2171a32eea94/image.png" alt=""></p>
<pre><code>function solution(A, B) {
  var answer = 0;
  A.sort((a, b) =&gt; a - b)
  B.sort((a, b) =&gt; a - b)
  let count = 0
  for (let i = 0; i &lt; A.length; i++) {
    if (A[count] &lt; B[i]) {
      count++;
      answer++;
    }
  }
  return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 가장 먼 노드]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%80%EC%9E%A5-%EB%A8%BC-%EB%85%B8%EB%93%9C</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%80%EC%9E%A5-%EB%A8%BC-%EB%85%B8%EB%93%9C</guid>
            <pubDate>Tue, 25 Oct 2022 21:22:31 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
n개의 노드가 있는 그래프가 있습니다. 각 노드는 1부터 n까지 번호가 적혀있습니다. 1번 노드에서 가장 멀리 떨어진 노드의 갯수를 구하려고 합니다. 가장 멀리 떨어진 노드란 최단경로로 이동했을 때 간선의 개수가 가장 많은 노드들을 의미합니다.</p>
<p>노드의 개수 n, 간선에 대한 정보가 담긴 2차원 배열 vertex가 매개변수로 주어질 때, 1번 노드로부터 가장 멀리 떨어진 노드가 몇 개인지를 return 하도록 solution 함수를 작성해주세요.</p>
<p><strong>제한사항</strong>
노드의 개수 n은 2 이상 20,000 이하입니다.
간선은 양방향이며 총 1개 이상 50,000개 이하의 간선이 있습니다.
vertex 배열 각 행 [a, b]는 a번 노드와 b번 노드 사이에 간선이 있다는 의미입니다.
<strong>입출력 예</strong>
<img src="https://velog.velcdn.com/images/noob-d/post/4ad362b9-f80e-485b-8c54-a915bc97825f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/noob-d/post/4aa69426-8a75-41d6-9435-3f6f77957a58/image.png" alt=""></p>
<pre><code>function solution(n, edge) {
    var answer = 0;
    const map = new Array(n + 1).fill(0)
    const vis = new Array(n + 1).fill(0)

    for (let i = 1; i &lt; map.length; i++) {
        map[i] = [];
    }

    edge.forEach((el) =&gt; {
        const [to, from] = el
        map[to].push(from)
        map[from].push(to)
    });

    vis[0] = -1

    const bfs = function(x) {
        const arr = [x]
        vis[x] = 1
        while (arr.length) {
            const ver = arr.shift()


            for (let i = 0; i &lt; map[ver].length; i++) {
                const next = map[ver][i]
                const w = !vis[next]
                if (vis[next] &gt; vis[ver] + 1 || w) {
                    arr.push(next)
                    vis[next] = vis[ver] + 1
                }
            }
        }
    }
    bfs(1)
    const max = Math.max(...vis)
    answer = vis.filter((el) =&gt; el === max).length
    return answer
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 단속 카메라]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A8%EC%86%8D-%EC%B9%B4%EB%A9%94%EB%9D%BC</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A8%EC%86%8D-%EC%B9%B4%EB%A9%94%EB%9D%BC</guid>
            <pubDate>Tue, 25 Oct 2022 21:22:23 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
고속도로를 이동하는 모든 차량이 고속도로를 이용하면서 단속용 카메라를 한 번은 만나도록 카메라를 설치하려고 합니다.</p>
<p>고속도로를 이동하는 차량의 경로 routes가 매개변수로 주어질 때, 모든 차량이 한 번은 단속용 카메라를 만나도록 하려면 최소 몇 대의 카메라를 설치해야 하는지를 return 하도록 solution 함수를 완성하세요.</p>
<p><strong>제한사항</strong></p>
<p>차량의 대수는 1대 이상 10,000대 이하입니다.
routes에는 차량의 이동 경로가 포함되어 있으며 routes[i][0]에는 i번째 차량이 고속도로에 진입한 지점, routes[i][1]에는 i번째 차량이 고속도로에서 나간 지점이 적혀 있습니다.
차량의 진입/진출 지점에 카메라가 설치되어 있어도 카메라를 만난것으로 간주합니다.
차량의 진입 지점, 진출 지점은 -30,000 이상 30,000 이하입니다.</p>
<p><strong>입출력 예</strong>
<img src="https://velog.velcdn.com/images/noob-d/post/be53f3ac-736e-4b74-882b-3ac4f0eb1657/image.png" alt=""></p>
<pre><code>function solution(routes) {
    let answer = 0;        
    routes.sort(function(x,y){
                return x[1]-y[1]
                })
    let camera = -30001
    routes.map((w)=&gt;{
        if(w[0] &gt; camera ){
            camera = w[1]
            answer ++
        }
    })
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[let, const]]></title>
            <link>https://velog.io/@noob-d/let-const</link>
            <guid>https://velog.io/@noob-d/let-const</guid>
            <pubDate>Tue, 25 Oct 2022 21:22:09 GMT</pubDate>
            <description><![CDATA[<p>앞서 다룬 내용은 var키워드로 전역변수로 선언하면 중복 선언 및 예상치 못한 문제를 야기해서 사용하지 않는게 좋다고 했다. let, const 키워드를 알아본다.</p>
<h2 id="let">let</h2>
<h3 id="변수-중복-선언-금지">변수 중복 선언 금지</h3>
<p>var 키워드는 변수 중복 선언이 가능했으나 let 키워드는 중복 선언시 문법 에러가 발생하게 된다.</p>
<pre><code>let test = &#39;hi&#39;
let test = &#39;bye&#39;    // syntaxError 발생</code></pre><h3 id="블록-레벨-스코프">블록 레벨 스코프</h3>
<p>var 키워드는 코드블록 사이에 선언된 변수도 전역 변수로 선언됐다. let키워드는 모든 코드 블록에서 지역 스코프로만 인정하는 블록 레벨 스코프를 따른다.</p>
<pre><code>let test = &quot;hi&quot;
if(true){
    let test = &quot;bye&quot;
    console.log(test)    // &quot;bye&quot; 같은 식별자명을 가진 변수지만 문맥상 지역 스코프의 변수 값을 참조
    let test2 = &quot;hello&quot;    //    코드 블록내에서 선언한 변수
}
console.log(test)    // &quot;hi&quot;
console.log(test2)    //    ReferenceError 코드 블록 내에서 선언한 변수는 지역 스코프를 가지기에 참조 못함</code></pre><h3 id="변수-호이스팅">변수 호이스팅</h3>
<p>변수 호이스팅에 대해 공부할때 let키워드로 선언한 변수는 호이스팅이 안되는것처럼 보였다.</p>
<pre><code>console.log(test)    // 레퍼런스 에러
let test</code></pre><p><strong>let 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 자바스크립트 엔진이 암묵적으로 선언단계를 진행하나 초기화 단계가 런타임시 선언문에 도달해야 진행</strong>된다. 선언 단계와 초기화 단계까지 참조 할 수 없는 구간을 <strong>일시적 사각지대</strong>라 부른다.
결국 먼저 선언 단계를 진행하니 호이스팅은 발생했다.</p>
<h2 id="const">const</h2>
<p>const 키워드는 상수를 선언할때 사용한다. 선언시 변수는 동시에 초기화를 해 줘야한다.</p>
<pre><code>const test    // SynataxError const로 선언 했지만 초기화를 하지 않았다

const test = 1;</code></pre><p>let 키워드와 마찬가지로 블록 레벨 스코프를 가지고 호이스팅이 발생하지 않는것 처럼 보인다.</p>
<h3 id="재할당-금지">재할당 금지</h3>
<p>const 키워드는 상수로 사용한다 했다. const 키워드로 선언한 변수는 재할당이 불가능하다.</p>
<pre><code>const test = 1
test = 2    // typeError</code></pre><h3 id="상수">상수</h3>
<p>상수는 재할당이 금지된 변수를 뜻한다. const 키워드로 선언된 변수에 원시값을 할당시 그 값은 변경이 불가능한 값이 된다. 상수는 대문자로 선언하거나 여러 단어로 이뤄진 경우는 언더코어(_)로 구분한다.</p>
<pre><code>const TAX_COST = 1.1    // 상수에 두 단어로 이뤄졌기에 언더코어로 상수명을 정했다. 세금율은 변하지 않기에 상수로 선언
function taxPrice (x) {    // 기본 가격에 세금 10%를 더해서 계산하는 함수
    return x * TAX_COST     
}
console.log(taxPrice(100))    // 110  기본 가격인 100에 10%인 10을 더한 값이 나온다</code></pre><h3 id="const-키워드와-객체">const 키워드와 객체</h3>
<p>const 키워드로 원시값을 할당시 변경이 불가능하다. 하지만 객체를 할당시 변경이 가능하다.</p>
<pre><code>const test = {
    x : 1
}
test.x = 2
console.log(test.x)    // 2</code></pre><p>const 키워드는 재할당이 금지일뿐 불변이 아니다.</p>
<h2 id="정리">정리</h2>
<p>우선순위 const &gt; let &gt; var(애는 안쓰는게 좋다.)
let 키워드를 쓰더라도 변수의 스코프를 최대한 좁게 만들어서 영향을 최소화 한다.
최대한 const 를 사용하다 나중에 문제시 바꾸자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 단어 변환]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A8%EC%96%B4-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A8%EC%96%B4-%EB%B3%80%ED%99%98</guid>
            <pubDate>Tue, 25 Oct 2022 08:20:55 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.
<img src="https://velog.velcdn.com/images/noob-d/post/17ea5f4b-185d-47a7-8043-5824d840347f/image.png" alt="">
예를 들어 begin이 &quot;hit&quot;, target가 &quot;cog&quot;, words가 [&quot;hot&quot;,&quot;dot&quot;,&quot;dog&quot;,&quot;lot&quot;,&quot;log&quot;,&quot;cog&quot;]라면 &quot;hit&quot; -&gt; &quot;hot&quot; -&gt; &quot;dot&quot; -&gt; &quot;dog&quot; -&gt; &quot;cog&quot;와 같이 4단계를 거쳐 변환할 수 있습니다.</p>
<p>두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.</p>
<p>제한사항
각 단어는 알파벳 소문자로만 이루어져 있습니다.
각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.
words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.
begin과 target은 같지 않습니다.
변환할 수 없는 경우에는 0를 return 합니다.
<strong>입출력 예</strong></p>
<p><img src="https://velog.velcdn.com/images/noob-d/post/53914dbe-770b-4322-93e8-b3d99f4b8bf2/image.png" alt=""></p>
<pre><code>function solution(begin, target, words) {
    var answer = 0;
    if (!words.includes(target)) {
        return answer
    }
    let q = [begin]
    let n = words.length
    let enter = Array(n).fill(0)

    const obj = {}
    for (let i in words) {
        obj[words[i]] = i
    }

    while (q.length &gt; 0) {
        let w = q.shift()
        if (w == target) {
            return enter[obj[w]]
        }
        for (let i in words) {
            if (enter[i] == 0) {
                let word = words[i]
                let dip = 0
                for (let j in words[i]) {
                    if (w[j] != words[i][j]) {
                        dip++
                    }
                    if (dip &gt; 1) {
                        break
                    }
                }
                if (dip == 1) {
                    q.push(words[i])
                    if (w == begin) {
                        enter[i] = 1
                    } else {
                        enter[i] = enter[obj[w]] + 1
                    }
                }
            }
        }
    }
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 야근 지수]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%95%BC%EA%B7%BC-%EC%A7%80%EC%88%98</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%95%BC%EA%B7%BC-%EC%A7%80%EC%88%98</guid>
            <pubDate>Tue, 25 Oct 2022 08:20:49 GMT</pubDate>
            <description><![CDATA[<p>문제 설명
회사원 Demi는 가끔은 야근을 하는데요, 야근을 하면 야근 피로도가 쌓입니다. 야근 피로도는 야근을 시작한 시점에서 남은 일의 작업량을 제곱하여 더한 값입니다. Demi는 N시간 동안 야근 피로도를 최소화하도록 일할 겁니다.Demi가 1시간 동안 작업량 1만큼을 처리할 수 있다고 할 때, 퇴근까지 남은 N 시간과 각 일에 대한 작업량 works에 대해 야근 피로도를 최소화한 값을 리턴하는 함수 solution을 완성해주세요.</p>
<p>제한 사항
works는 길이 1 이상, 20,000 이하인 배열입니다.
works의 원소는 50000 이하인 자연수입니다.
n은 1,000,000 이하인 자연수입니다.
입출력 예
<img src="https://velog.velcdn.com/images/noob-d/post/2f5ad8c0-a93e-43c5-b263-b06f8164c113/image.png" alt=""></p>
<pre><code>function solution(n, works) {
    while(n &gt; 0){
        works = works.sort((a,b) =&gt; {return b-a})
        works[0] = works[0] - 1
        n--
    }
    return works.map(a =&gt; {return a * a}).reduce((a,b) =&gt; {return a+b})
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 최고의 집합]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EA%B3%A0%EC%9D%98-%EC%A7%91%ED%95%A9</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EA%B3%A0%EC%9D%98-%EC%A7%91%ED%95%A9</guid>
            <pubDate>Tue, 25 Oct 2022 08:20:33 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
자연수 n 개로 이루어진 중복 집합(multi set, 편의상 이후에는 &quot;집합&quot;으로 통칭) 중에 다음 두 조건을 만족하는 집합을 최고의 집합이라고 합니다.</p>
<p>각 원소의 합이 S가 되는 수의 집합
위 조건을 만족하면서 각 원소의 곱 이 최대가 되는 집합
예를 들어서 자연수 2개로 이루어진 집합 중 합이 9가 되는 집합은 다음과 같이 4개가 있습니다.
{ 1, 8 }, { 2, 7 }, { 3, 6 }, { 4, 5 }
그중 각 원소의 곱이 최대인 { 4, 5 }가 최고의 집합입니다.</p>
<p>집합의 원소의 개수 n과 모든 원소들의 합 s가 매개변수로 주어질 때, 최고의 집합을 return 하는 solution 함수를 완성해주세요.</p>
<p><strong>제한사항</strong>
최고의 집합은 오름차순으로 정렬된 1차원 배열(list, vector) 로 return 해주세요.
만약 최고의 집합이 존재하지 않는 경우에 크기가 1인 1차원 배열(list, vector) 에 -1 을 채워서 return 해주세요.
자연수의 개수 n은 1 이상 10,000 이하의 자연수입니다.
모든 원소들의 합 s는 1 이상, 100,000,000 이하의 자연수입니다.
입출력 예
<img src="https://velog.velcdn.com/images/noob-d/post/d5fbf6f7-8b6c-4179-9c51-a8ec477d9251/image.png" alt=""></p>
<pre><code>function solution(n, s) {
  var answer = [];
  if (n &gt; s) {
      answer.push(-1)
  }else{
      answer = Array.from({length:n}, () =&gt; parseInt(s / n))
    for(let i = parseInt(s % n); i &gt; 0; i--){
        answer[--n]++
    }
  }
  return answer
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 이중우선순위큐]]></title>
            <link>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90</link>
            <guid>https://velog.io/@noob-d/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90</guid>
            <pubDate>Tue, 25 Oct 2022 08:20:14 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
이중 우선순위 큐는 다음 연산을 할 수 있는 자료구조를 말합니다.
<img src="https://velog.velcdn.com/images/noob-d/post/3ad35c92-5345-4266-8706-b1b348adf242/image.png" alt=""></p>
<p>명령어    수신 탑(높이)
I 숫자    큐에 주어진 숫자를 삽입합니다.
D 1    큐에서 최댓값을 삭제합니다.
D -1    큐에서 최솟값을 삭제합니다.
이중 우선순위 큐가 할 연산 operations가 매개변수로 주어질 때, 모든 연산을 처리한 후 큐가 비어있으면 [0,0] 비어있지 않으면 [최댓값, 최솟값]을 return 하도록 solution 함수를 구현해주세요.</p>
<p><strong>제한사항</strong>
operations는 길이가 1 이상 1,000,000 이하인 문자열 배열입니다.
operations의 원소는 큐가 수행할 연산을 나타냅니다.
원소는 “명령어 데이터” 형식으로 주어집니다.- 최댓값/최솟값을 삭제하는 연산에서 최댓값/최솟값이 둘 이상인 경우, 하나만 삭제합니다.
빈 큐에 데이터를 삭제하라는 연산이 주어질 경우, 해당 연산은 무시합니다.
입출력 예
<img src="https://velog.velcdn.com/images/noob-d/post/57c068e3-ae41-4d81-acb9-bb1433a133d5/image.png" alt=""></p>
<pre><code>function solution(operations) {
    const arr = [];

    operations.forEach(v =&gt; {
        const [oper, num] = v.split(&#39; &#39;);

        if (oper == &#39;I&#39;){
        arr.push(parseInt(num))
        }
        if (oper == &#39;D&#39; &amp;&amp; arr.length) {
            if (num == 1) {
            arr.splice(arr.indexOf(Math.max(...arr)), 1)
            }
            if (num == -1) {
            arr.splice(arr.indexOf(Math.min(...arr)), 1)
            }
        }
    })
    return [Math.max(...arr) | 0 , Math.min(...arr) | 0];
}
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[전역 변수]]></title>
            <link>https://velog.io/@noob-d/%EC%A0%84%EC%97%AD-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@noob-d/%EC%A0%84%EC%97%AD-%EB%B3%80%EC%88%98</guid>
            <pubDate>Tue, 25 Oct 2022 08:19:52 GMT</pubDate>
            <description><![CDATA[<p>전역 변수는 많이 사용하면 참조하는 모든 값에 영향을 끼쳐 코드의 흐름을 읽기 힘들어지고 생명주기가 길어 메모리 리소스도 오랜 기간 소비하게 된다. 이해하기 편하려면 바탕화면에 안녕하세요.txt 파일이 있고 폴더를 만들어 내부에 안녕하세요.txt 파일을 만들었는데 바탕화면에 있는 txt파일에도 영향을 끼치게 된다고 보면 된다.</p>
<h2 id="변수의-생명주기">변수의 생명주기</h2>
<p>변수는 선언에 이해 생성되고 할당을 통해 값을 가진다. 전역 변수의 생명주기는 애플리케이션의 생명 주기와 같지만 함수 내부에서 선언된 변수는 함수의 호출에 생성 종료에 소멸한다.
전역 변수 같은경우는 호이스팅에 의해 코드 한줄씩 실행되기 전에 선언된다고 배웠다.
하지만 함수 내부에 있는 지역 변수 같은경우 함수의 호출에 의해 먼저 변수가 선언된 후 코드가 한줄씩 실행된다.
<img src="https://velog.velcdn.com/images/noob-d/post/7d4c5df0-f88a-4aa1-9cc6-32ca0cc09c55/image.png" alt="">
함수에 선언된 변수의 생명주기</p>
<blockquote>
<p>전역 객체??
코드가 실행되기전 먼저 생성되는 특수한 객체다. <strong>window,self,this,frames,global 식별자가 존재했으나 globalThis로 통일됐다</strong>.</p>
</blockquote>
<h2 id="전역-변수를-줄이자">전역 변수를 줄이자</h2>
<p>이제 전역 변수가 어떤 특성화 흐름을 가졌고 어떤 문제점을 가지는지 이해했다. 줄여보자</p>
<h3 id="즉시-실행-함수">즉시 실행 함수</h3>
<p>전에 다뤘었는데 함수 정의와 동시에 호출되고 한번만 호출되는 특성을 가졌다. 생명주기에 의해 함수 종료와 동시에 변수도 삭제된다.</p>
<pre><code>(function () {    
    return 1 + 2
}())</code></pre><h3 id="네임-스페이스-객체">네임 스페이스 객체</h3>
<p>네임스페이스는 전역 변수처럼 사용할 변수를 프로퍼티로 추가하는 방법이다.</p>
<pre><code>var global = {} // 객체 생성
global.person = {
    name: &quot;hi&quot;
}
console.log(global)</code></pre><h3 id="모듈-패턴">모듈 패턴</h3>
<p>클래스와 비슷하다. 변수와 함수를 싹 모와다 즉시 실행함수()로 감싸 하나의 모듈을 만든다. 전역 변수의 제거와 캡슐화를 구현 할 수있다. 캡슐화는 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 메서드를 하나로 묶는걸 말한다. 객체의 프로퍼티나 메서드를 감출 목적으로 사용하기도 하는데 정보 은닉이라 한다.</p>
<pre><code>var result = (function () {
    var num = 0    // 프라이빗 멤버
    return {
        increase() {    // 퍼블릭 멤버
            return ++num
        },
        decrease() {    //    퍼블릭 멤버
            return --num
        }
    }
}())
console.log(result.increase())    //    1    
console.log(result.decrease())    //    0    
console.log(result.num)        // undefined 변수를 정보 은닉했다. </code></pre><h2 id="es6-모듈">ES6 모듈</h2>
<p>ES6 모듈을 사용하면 전역 변수를 사용 할 수 없다. script 태그에 어트리뷰트를 추가하면 자바스크립트 파일은 모듈로서 동작한다</p>
<pre><code>&lt;script type=&quot;module&quot; src=&quot;lib.mjs&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;module&quot; src=&quot;app.mjs&quot;&gt;&lt;/script&gt;</code></pre><p>단 아직 구형 브라우저에서는 동작하지 않으며 트랜스 파일링이나 번들링이 필요하기 때문에 아직은 Webpack등의 모듈 번들러를 사용한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스코프]]></title>
            <link>https://velog.io/@noob-d/%EC%8A%A4%EC%BD%94%ED%94%84</link>
            <guid>https://velog.io/@noob-d/%EC%8A%A4%EC%BD%94%ED%94%84</guid>
            <pubDate>Tue, 25 Oct 2022 08:19:45 GMT</pubDate>
            <description><![CDATA[<p>스코프는 유효범위를 뜻한다. 앞서 다룬 함수에서도 함수 몸체 내부에서만 참조 할 수 있다는게 스코프다.</p>
<pre><code>function add(x,y) {
    return x + y
}
add(1,2)    // 3
console.log(x,y)    // 레퍼런스 에러</code></pre><p>그럼 함수내에서 선언한 함수는 어디까지 참조 할 수 있을까?</p>
<pre><code>function out() {        
    let x = 1
    function inn() {
        let y = 2
        x = y
    }
    inn()
    return x
}
out()    // 2 함수내에서 선언한 함수인 inn이 외부 함수에서 선언한 x에 접근 했다

function out() {        
    let x = 1
    function inn() {
        let y = 2
    }
    inn()
    x = y
    return x
}
out()    // 레퍼런스 에러 Y를 참조하지 못함</code></pre><p>즉 스코프는 식별자가 유효한 범위를 말한다.
그럼 함수 외부와 내부에 같은 이름의 식별자가 있는경우는 어떻게 동작하는지 확인한다.</p>
<pre><code>let x = 1
function test() {

    let x = 2
    console.log(x)
}
test()
console.log(x)
// 2 1 같은 식별자명을 가졌지만 참조하는 식별자는 각각 다른걸 확인 했다.</code></pre><p>같은 이름의 변수 중 참조할 변수를 찾는걸 식별자 결정이라 한다. 자바스크립트는 스코프를 통해 어떤 변수를 참조할지 결정하기에 위에 같은 결과가 나온다.</p>
<blockquote>
<p>렉시컬 환경??
코드가 어디서 실행되어 주변에 어떤 코드가 있는지를 말한다. 코드의 문맥은 렉시컬 환경으로 이뤄지고 모든 코드는 실행 컨텍스트에서 평가되고 실행된다.</p>
</blockquote>
<h2 id="종류">종류</h2>
<p>전역과 지역으로 구분 할 수 있다.
<strong>전역은 코드의 가장 바깥 영역을 뜻하고 지역은 함수 몸체 내부를 뜻한다</strong>.
<img src="https://velog.velcdn.com/images/noob-d/post/5771f591-696a-4b6e-b3e3-630995007aac/image.png" alt=""></p>
<p>전역에서 선언된 변수는 어디서든 참조 가능하다. 하지만 지역에서 선언된 변수는 지역 내 자신의 하위 지역 스코프에서만 유효하다.</p>
<h3 id="스코프-체인">스코프 체인</h3>
<p>저번에 함수 내부에서 함수를 정의하는걸 중첩 함수라 했고 중첩 함수를 포함하는 겉을 외부 함수라 했다. 
때문에 함수는 중첩이 가능하며 스코프 또한 중첩이 가능하게 된다. 외부 함수에서 선언된 변수는 중첩 함수에서 참조 가능하다 그 반대는 불가능 하다.</p>
<h2 id="함수레벨-스코프">함수레벨 스코프</h2>
<p>자바스크립트는 코드 블록 말고 함수에만 지역 스코프가 생성된다. 코드 블록에서도 스코프가 생성된다면 블록 레벨 스코프라하고 반대는 함수 레벨 스코프라 한다.</p>
<pre><code>var x = 1
if(1){
    var x = 2
}
console.log(x)    // 2 if안에서 var 키워로드 x가 선언됐지만 함수가 아닌 코드 블록이기 때문에 전역 변수다.</code></pre><h2 id="렉시컬-스코프">렉시컬 스코프</h2>
<p>자바스크립트는 렉시컬 스코프를 따른다. 함수를 어디서 호출했는지가 아니라 함수를 어디서 정의 했는지에 따라 상위 스코프가 정해진다.</p>
<pre><code>var x = 1
function first() {
    var x = 2
    second()
}
function second() {
    console.log(x)
}

first()        //  1    함수 내부에서 second 함수를 호출 했기 때문에 참조하는 값이 2일줄 알았지만 스코프는 바뀌지 않았다.
second()    //    1</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[함수]]></title>
            <link>https://velog.io/@noob-d/%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@noob-d/%ED%95%A8%EC%88%98</guid>
            <pubDate>Tue, 25 Oct 2022 08:19:38 GMT</pubDate>
            <description><![CDATA[<h2 id="함수">함수</h2>
<p>함수의 기본은 입력을 받아 출력을 내보내는 과정을 정의한 것이다.
<img src="https://velog.velcdn.com/images/noob-d/post/0617fc35-c623-497b-a508-950d0c8b44eb/image.png" alt=""></p>
<h3 id="그림에-있는-함수를-코드로-작성">그림에 있는 함수를 코드로 작성</h3>
<pre><code>function add(x,y){
    return x + y
}

add(1,2)    // 3</code></pre><p><img src="https://velog.velcdn.com/images/noob-d/post/cd415565-8d97-4ad1-92fe-94bdb3ecc006/image.png" alt=""></p>
<p>그럼 굳이 이렇게 함수의 형태를 안만들고도 연산을 할 수 있지 않나 싶지만
함수를 사용 시 <strong>코드의 재사용성</strong>, 1+2, 3+4, 1+6등 같은 코드를 중복 사용 시 함수를 이용하면 수정 시 시간이 줄어 <strong>유지 보수의 편의성이 높고 코드를 보기가 편해진다</strong>.</p>
<h3 id="함수-리터럴">함수 리터럴</h3>
<p>자바스크립트에서 함수는 객체 타입의 값이다. 함수 리터럴도 평가되어 값을 생성한다.</p>
<h3 id="함수-정의법-4가지">함수 정의법 4가지</h3>
<pre><code>함수 선언문 
function add(x,y) {
    return x + y
} // 함수 선언문은 표현식이 아닌 문이다. 즉 변수에 할당 할 수 없다..

함수 표현식
const add = funtion(x,y) {
    return x+y
}

Function 생성자 함수
const add = new Function(&#39;x&#39; , &#39;y&#39;, &#39;return x + y&#39;)

화살표 함수
const add = (x,y) =&gt; x + y</code></pre><h3 id="함수의-선언">함수의 선언</h3>
<pre><code>function add(x,y) {
    return x + y
}</code></pre><p>함수명 add는 몸체 내부에서만 유효한 식별자인 함수 이름이다. 따라서 add로 함수는 본래라면 호출 할 수 없어야 한다. 함수를 호출 하려면 add가 함수 객체를 가리키는 식별자여야 한다.
그럼에도 add로 함수는 호출이 된다 왤까.</p>
<p>자바스크립트 엔진이 암묵적으로 생성한 식별자로 add를 만들었기 때문이다. 함수 객체를 가리키는 식별자가 없으면 함수 객체를 참조, 호출이 불가능하다 그래서 자바스크립트 엔진이 함수 이름과 동일한 식별자를 생성한 후 함수 객체를 할당한다.</p>
<p>결론 <strong>add는 함수 이름으로 호출하는게 아니라 함수 객체를 나타내는 add를 가리키는 식별자로 호출한다</strong>.</p>
<h3 id="함수-표현식">함수 표현식</h3>
<p>표현식이기에 식별자에 함수를 할당 할 수 있다. 
자바스크립트에서 함수는 일급 객체이기때문에 값으로써 자유롭게 사용 가능하다.</p>
<h2 id="함수와-호이스팅">함수와 호이스팅</h2>
<pre><code>console.log(add(1,2))    // 3 함수 선언이 아래에 있는데도 콘솔찍힘 호이스팅임
console.log(add2(1,2))    // 타입에러 함수 표현식이라 함수 선언식과 생성 시점이 다름

function add(x,y){
    return x + y
}

var add2 = function(x, y) {    // 함수 표현식으로 정의한 함수는 이후에 호출해야 한다.
    return x + y
}</code></pre><p>근데 <strong>함수를 호출하기 전에 함수를 선언해야 한다는 규칙때문에 함수 선언문보단 함수 표현식을 사용하는걸 권장</strong>한다.</p>
<h2 id="function-생성자-함수">Function 생성자 함수</h2>
<p>빌트인 함수인 Function(대문자 주의) 생성자 함수에 매개변수, 함수 몸체를 &quot;문자열&quot;로 전달하면서 new 연산자와 함께 호출하면 함수 객체를 생성한다. 근데 new 연산자의 차이는 잘 모르겠다.
생성자 함수는 클로저를 생성하지 않는 등 다르게 동작한다.</p>
<blockquote>
<p>클로저?</p>
</blockquote>
<pre><code>const add = (function () {
    const a = 1
    return function(x,y){
        return x + y+ a
    }    
    // 함수 표현식의 반환값으로 함수를 리턴했다. 이런걸 클로저라 한다
}())
add(1,2)    // 4 정상적으로 리턴 함수에 접근한다
const add2 = (function () {
    const a = 1
    return new Function(&#39;x&#39;,&#39;y&#39;,&#39;return x + y + a&#39;)    
    // 함수 표현식의 반환값으로 생성자 함수를 리턴했다.
}())
add2(1,2)    //    레퍼런스에러 클로저를 생성하지 못한다;</code></pre><h2 id="화살표-함수">화살표 함수</h2>
<p>function 키워드 없이 화살표를 &quot;=&gt;&quot; 사용하여 간략한 방법으로 함수를 선언한다.</p>
<pre><code>const add = (x,y) =&gt; x+y
add(1,2)    // 3
</code></pre><p><strong>단순히 함수 표현식을 간략화 한게 아니라 내부 동작 또한 다르다. 생성자 함수로는 사용 불가능 하고 기본 함수와 this 바인딩 방식이 다르다. prototype프로퍼티가 없고 인수 객체를 생성 안한다</strong>. </p>
<h2 id="인수-확인">인수 확인</h2>
<p><strong>매개변수보다 더 많은 인수를 전달했을 시.</strong></p>
<pre><code>function add(x,y) {        // 매개변수는 x와 y 뿐인데 인수를 더 넘겨주면 어찌될까
    console.log(arguments)    // arguments 객체안에 저장된다, 인덱스로 접근 가능
    return x + y
}
add(1,2,3,4)</code></pre><p><strong>매개변수보다 더 적은 인수를 전달했을 시.</strong></p>
<pre><code>function add(x,y) {        
    x = x || 0        
    y = y || 0        // 원래 매겨변수 y는 아무런 인수를 받은게 없어 undefined지만 단축평가로 오류 내지 않고 결과 값을 얻을 수 있다
    return x + y
}
add(1)    // 1

function add(x = 0,y = 0) {    // 또는 매개변수 기본 값을 이용하는 방법도 있다        
    return x + y
}
add(1)    // 1</code></pre><p><strong>매개변수는 최대 개수의 제한은 없지만 함수의 이해를 힘들게 하고 유지보수가 힘들다.
이상적인 매개변수는 0이며 함수는 한가지 일만 한다</strong>.</p>
<h2 id="즉시-실행-함수">즉시 실행 함수</h2>
<p>함수 정의와 동시에 즉시 호출되는 함수다. 재 호출이 불가능하다.</p>
<pre><code>(function () {    // 함수 식별자가 없다. 넣어도 되지만 그릅 연산자내의 함수 리터럴로 평가되어 함수 몸체에서만 참조 가능한 식별자가 되어 호출은 마찬가지로 불가능하다.
    return 1 + 2
}())

const add = (function (x,y) {    // 즉시 실행 함수도 값을 반환 할 수 있고 인수 전달도 가능하다.
    return x + y
}(1,2))
console.log(add)    // 3</code></pre><h2 id="재귀-함수">재귀 함수</h2>
<p>함수가 자기 자신을 호출하는 걸 재귀 호출이라 한다. 코딩 테스트할때 시간 복잡도를 낮추기 위해 자주 사용한다.</p>
<pre><code>    function count(n){    // 반복문으로 0이 될때까지 카운트하는 함수
        for(let i = n; i &gt;= 0; i--){
            console.log(i)
        }
    }
    count(5)    // 5 4 3 2 1 0

    function count(n){    // 재귀로 0이 될때까지 카운트하는 함수
        if(n &lt; 0){    // 만약 0이 된다면 멈추라는 조건문
            return
        }
        console.log(n)
        count(n-1)    // count 함수안에 count 호출이 있다.
    }
    count(5)    // 5 4 3 2 1 0</code></pre><h2 id="중첩-함수">중첩 함수</h2>
<p>함수 내부에 정의된 함수를 중첩 함수 또는 내부 함수라 한다. 중첩 함수의 호출은 외부 함수 내부에서만 가능하다.</p>
<pre><code>function out() {        
    const x = 1
    function inn() {
        const y = 2
        console.log(x + y)
    }
    inn()
}
out()    // 3
inn()    // 레퍼런스 에러</code></pre><p>if문이나 for문 등에서도 함수 선언이 가능하지만 호이스팅에 의한 혼란이 있을 수 있으므로 안하는게 좋다. </p>
<h2 id="콜백-함수">콜백 함수</h2>
<p>함수의 배개변수를 통해 <strong>함수의 내부로 전달되는 함수를 콜백 함수</strong>라 한다. 그리고 <strong>전달 받아진 외부 함수를 고차 함수</strong>라 한다.</p>
<pre><code>function result(x, y, f){    // 매개변수 f는 함수를 추상화 시킨다. 고차함수
    return f(x,y)
}

const add = function (x, y){    // 콜백 함수로 매개변수를 더해준다
    return x + y
}

const multiple = function (x, y){    
    return x * y
}

result(1,2,add)        // 3
result(1,2,multiple)    // 2</code></pre><p>비동기 처리에서도 많이 쓰인다.</p>
<pre><code>document.getElementById(&#39;button&#39;).addEventListener(&#39;click&#39;, function () {console.log(&#39;button click&#39;)})</code></pre><p>배열 고차함수에서의 콜백 함수</p>
<pre><code>const arr = [0,1,2].map(function (x) {    // map 함수는 배열 0부터 끝까지 순회한다
    return x + 1    // 순회할때 해당 인덱스 배열에 접근해 +1을 해준다
})
console.log(arr) //[1, 2, 3]</code></pre><h2 id="순수-함수">순수 함수</h2>
<p>외부 상태를 변경하지 않는 함수는 순수함수, 그 반대는 비순수 함수라 한다.</p>
<pre><code>function add (x){    // 순수함수
    return x + 1
}

const count = 0
function add (){    // 비순수 함수
    return count + 1
}
</code></pre><p><strong>비순수 함수가 외부 상태의 변경을 하면 쉽게 추적하기 힘드므로 최대한 순수 함수를 이용하는것이 옳다</strong>.</p>
]]></description>
        </item>
    </channel>
</rss>