IIFE (Immediately Invoked Funtion Expressions)?

IIFE(즉시 호출 함수 표현식)은 주로 이름 충돌 최소화 및 private 변수 생성에 사용되는 자바스크립트 디자인 패턴이다.
(function(){ 
  console.log('IIFE'); 
})();

함수 표현식으로서 익명 또는 기명 함수를 만들고는, 그 즉시 함수 호출을 함

 

"이 안에 들어있는 코드를 바로 실행하라" 하는 표현으로 이해하자.

 

 

함수 선언문과 함수 표현식?

함수 선언은 함수 이름을 생략할 수 없고, 자바스크립트의 실행 컨텍스트에 로딩되어 있으므로 언제든지 호출할 수 있다.

함수 표현식은 값으로서 평가되며, 익명함수로 나타낼 수 있고, 인터프리터가 해당 라인에 도달하였을 때만 실행됨

 

함수 선언을 괄호 연산자로 그룹핑해주면 함수 표현식으로 나타낼 수 있다.

halo() //호이스팅으로 인해 오류가 나지 않는다, 출력: halo

function halo() {
  console.log('halo')
}


// 익명함수로 사용
(function(){
	console.log("foo")
})() //출력: foo

// 기명함수로 사용
(function foo() {
    console.log('foo')
})() // 함수선언문이 함수표현식으로 바뀌었고 IIFE로 인해서 즉시 호출된다, 출력: foo

foo() //ReferenceError: foo is not defined
//함수 이름인 foo는 함수 몸체에서만 참조할 수 있는 식별자이므로 IIFE를 다시 호출할 수 없다.

 

IIFE의 구조

일반적으로 아래와 같은 두가지 방법으로 사용한다

(function(){ console.log('IIFE'); })();
( function(){ console.log('IIFE'); }() );

ES6에서 도입된 화살표함수도 함께 사용할 수 있다.

(() => console.log('IIFE with arrow'))();

(() => {
    console.log('IIFE with arrow')
})()

 

언제, 왜 사용하나요?

1. 이름 충돌 최소화

=> 불필요한 전역 변수와 함수를 생성하지 않는 것이 좋다

 

프로그램 초기화 시점에 init 함수를 실행한다고 가정하자.

function init() {
  var operate = 'init';
  console.log(operate)
}
init()

이 함수는 전역 scope에 선언되어 이름 충돌이 발생할 확률이 높다. 

개발자 의도와는 달리, 다른 코드에서 init 함수가 재호출될 수도 있다.

(function init() {
  var operate = 'init';
  console.log(operate)
})()

따라서, 외부 코드로부터 사용되지 않는, 단 한 번 호출하는 코드들, 변수와 함수들은 IIFE를 사용하여 전역 scope 오염을 방지하고 다른 개발자가 실수로 호출할 수 없게 해준다.

=> 즉시 실행한 뒤에 전역에서 사라지기 때문에 전역 scope와 충돌하지 않는 것이다.

 

2. clousure와 private 데이터

IFE의 장점은 내부에 있는 것들이 모두 자신만의 스코프를 가지지만, IIFE 자체는 함수이므로 스코프 밖으로 무언가를 내보낼 수 있다는 것이다.

const greet = (function() {
	const secret = "비밀"
return `비밀의 길이는 ${secret.length}이다.`;
})()

console.log(greet) //비밀의 길이는 2 이다

변수 secret은 IIFE 스코프 안에서 안전하게 보호되며 외부에서 접근할 수도 없다.

 

IIFE는 함수이므로 무엇이든 반환할 수 있으며, 배열, 객체, 함수를 반환할 수도 있다

const getCount = (function(){
  let count = 0;
  return function() {
    ++count;
    return count;
  }
})();

console.log(getCount()); // 1
console.log(getCount()); // 2

IIFE 안의 익명함수는 closure가 되며, 변수 count는 private data로, IIFE 안에 안전하게 보관되어 있으므로 전역에서 접근이 안된다.

  • getCount 변수외부함수(IIFE)를 실행한 결과를 저장한다. 처음 한번만 실행되기 때문에 count는 0으로 저장되며 내부함수(익명함수)를 반환한다.
  • getCount()가 호출될 때마다 내부함수가 실행되기 때문에 count변수가 증가하고 반환되기 때문에 콘솔에 나타나는 것은 내부 함수에서 반환한 업데이트된 count값이다.

 

이를 모듈 패턴이라고도 한다. (클로저를 기반으로 동작하면서, 전역변수의 억제는 물론 캡슐화까지 구현)

 

3. 변수의 별칭

만약, jQuery와 또다른 라이브러리를 사용하고 있는데, 둘다 $을 전역 변수로 사용한다면 충돌 문제가 생길 수 있다.

이럴 때, jQuery를 인자로 받는 IIFE 블럭으로 감싸주면 블록 내의 $가 jQuery로 정의되면서 충돌을 방지할 수 있게 된다.

(function($) {
  //예시 코드
   $("p").on("click", function() {
       $("p").css("color", "red");
    });
})(jQuery)

 

4. 자주 사용되는 특정한 키워드를 압축

(function(window, document, undefined) {
   window.alert("안녕")
   document.write("반가워")
})(window, document);

이 코드를 압축해보면,

(function(a, b, c) {
   a.alert("안녕")
   b.write("반가워")
})(window, document);

매개변수로 받은 window, document, undefined를 a,b,c 라는 토큰으로 지정해주기 때문에 

이 IIFE 블록 내에 있는 모든 window 키워드는 a로 대체할 수 있다.

-> 스크립트가 길면 길수록, 이 방식으로 파일의 용량을 크게 줄일 수 있다.

 

 

참고, 출처:

https://velog.io/@bisu8018/JS-IIFEImmediately-Invoked-Function-Expressions-%EB%9E%80

http://chanlee.github.io/2014/01/11/understand-javascript-iife/

https://medium.com/sjk5766/iife-immediately-invoked-function-expression-%EC%A0%95%EB%A6%AC-53ab6543b828

https://findawayer.tistory.com/entry/IIE%EC%9D%98-%EC%9D%98%EB%AF%B8%EB%8A%94

https://code-masterjung.tistory.com/65

'엘리스 ai 트랙 > FE' 카테고리의 다른 글

기본값+rest+spread  (0) 2022.03.07
구조분해할당  (0) 2022.03.07
var vs let vs const  (0) 2022.02.21
스코프  (0) 2022.02.14
BFC (Block Formatting Context)  (0) 2022.02.05

변수(Variable)

고유한 식별자(변수명)에 의해 구별해서 값을 참조할 수 있다.

식별자는 데이터가 저장된 메모리 상의 주소를 기억해서 메모리에 저장된 값을 참조한다.

 

식별자(변수명) 명명 규칙

  • 반드시 영문자(특수문자 제외), underscore ( _ ), 또는 달러 기호($)로 시작하여야 한다. 이어지는 문자에는 숫자(0~9)도 사용할 수 있다.
  • 자바스크립트는 대/소문자를 구별하므로 사용할 수 있는 문자는 “A” ~ “Z” (대문자)와 “a” ~ “z” (소문자)이다.

동적 타입 언어

자바스크립트는 동적 타입 언어.

타입 지정 없이 값이 할당되는 과정에서 값의 타입에 의해서 자동으로 타입이 결정됨. 

같은 변수에 여러 타입의 값을 할당가능. 이를 동적 타이핑

var foo;

console.log(typeof foo);  // undefined

foo = null;
console.log(typeof foo);  // object

foo = {};
console.log(typeof foo);  // object

foo = 3;
console.log(typeof foo);  // number

foo = 3.14;
console.log(typeof foo);  // number

foo = 'Hi';
console.log(typeof foo);  // string

foo = true;
console.log(typeof foo);  // boolean

 

var vs let vs const 

  var let const
global scope o x x
script scope x o o
functional local scope o o o
block scope x o o
재선언 o x x
재할당 o o x

이고잉님 유튜브 참고: https://www.youtube.com/watch?v=61iolhWgQt0&t=543s

 

 

ES5까지는 변수를 참조할 수 있는 방법은 var 키워드밖에 없었음

var은 타 언어와 달리 여러 특징이 있는데 이것은 심각한 문제를 일으킬 수 있다

  1. 함수레벨 스코프
    => for 문의 변수 선언문에서 선언한 변수를 for 문의 코드 블록 외부에서 참조할 수 있다, 전역변수의 남발
    for(var i=0; i<5; i++){
        console.log(i) // 0, 1, 2, 3, 4
    }
    console.log(i) //5​
  2. var 키워드 생략 허용
  3. 변수 중복 선언 허용
  4. 변수 호이스팅
    => 변수를 선언하기 전에 참조 가능

=> 대부분의 문제는 전역변수로 인해 발생, 전역변수는 유효범위가 넓어서 어디서 어떻게 사용할지 파악하기 힘들며 복잡성을 증가시킬 수 있다. 따라서 변수의 스코프는 좁을수록 좋다

 

=> ES6부터 나온 let과 const가 var의 단점을 보완하기 위해 도입

 

let

  1. 블록레벨 스코프
    for(let i=0; i<5; i++){
    	console.log(i) //0, 1, 2, 3, 4
    }
    console.log(i) //Uncaught ReferenceError: i is not defined
  2. 변수 중복 선언 금지
    var foo = 123;
    var foo = 456;  // 중복 선언 허용
    
    let bar = 123;
    let bar = 456;  // Uncaught SyntaxError: Identifier 'bar' has already been declared
  3. 호이스팅 - 일시적 사각지대 (Temporal Dead Zone)
    **호이스팅(Hoisting): var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성

    변수가 선언문 이전에 참조하면 var는 undefined를 반환하지만 let은 ReferenceError가 발생한다.
    -> let 선언은 var 선언과 달리 TDZ에 의해 제약을 받는다.

    console.log(foo) //undefined
    var foo;​

    var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. (호이스팅)
    변수 선언문 이전에 변수에 접근하여도 에러가 발생하지 않는다.  
    console.log(bar); // Error: Uncaught ReferenceError: bar is not defined => TDZ
    let bar; // let bar = undefined; 와 같다, 변수 선언문에서 초기화가 이루어진다.
    
    console.log(bar); // undefined
    
    bar = 1; // 할당문에서 할당 단계가 실행된다.
    console.log(bar); // 1

    let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.
    선언단계만 호이스팅되기 때문에 초기화 이전에 변수에 접근하려고 하면 Reference Error가 발생한다
    그래서 초기화 단계가 진행돼야 참조할 수 있게 된다. (let 변수는 변수 선언문에서 초기화가 이루어진다.)
    변수 선언문 이후에 변수에 접근해야 에러가 발생하지 않는다.


    스코프의 선두부터 초기화 지점까지의 구간을 일시적 사각지대 (Temporal Dead Zone)이라고 부른다
    코드 실행이 변수가 실제 있는 위치에 도달할 때까지 액세스할 수 없는 것이다.
    let 변수가 선언된 시점에서 제어 흐름은 TDZ를 떠난 상태이며, 변수를 사용할 수 있게 된다.

 

const

  1. 블록레벨 스코프
  2. let은 재할당이 자유로우나 const는 재할당이 금지
    => const는 반드시 선언과 동시에 할당이 이루어져야 한다
    const FOO = 123;
    FOO = 456; // TypeError: Assignment to constant variable.
    const FOO; // SyntaxError: Missing initializer in const declaration
  3. 상수
  4. const와 객체
    => const는 재할당은 불가능하지만 할당된 객체의 내용(프로퍼티의 추가, 삭제, 프로퍼티 값의 변경)은 변경할 수 있다.
    const user = { name: 'Lee' };
    
    // 객체의 내용은 변경할 수 있다.
    user.name = 'Kim';
    
    console.log(user); // { name: 'Kim' }

 

결론, 정리

  • 재할당이 필요치 않은 원시 값과 객체에는 const 키워드를 사용한다
  • 재할당이 필요한 경우에 한정해 let 키워드를 사용한다. 이때 변수의 스코프는 최대한 좁게 만든다
  • ES6를 사용한다면 var 키워드는 사용하지 않는다.

 

 

참고, 출처:

https://poiemaweb.com/es6-block-scope

https://poiemaweb.com/js-data-type-variable

https://medium.com/korbit-engineering/let%EA%B3%BC-const%EB%8A%94-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85-%EB%90%A0%EA%B9%8C-72fcf2fac365

 

https://www.youtube.com/watch?v=61iolhWgQt0&t=543s 

 

'엘리스 ai 트랙 > FE' 카테고리의 다른 글

구조분해할당  (0) 2022.03.07
IIFE (즉시 호출 함수 표현식)  (0) 2022.02.28
스코프  (0) 2022.02.14
BFC (Block Formatting Context)  (0) 2022.02.05
z-index  (0) 2022.02.02

https://github.com/tony9402/baekjoon

 

GitHub - tony9402/baekjoon: 코딩테스트 대비 문제집(Baekjoon Online Judge)

코딩테스트 대비 문제집(Baekjoon Online Judge). Contribute to tony9402/baekjoon development by creating an account on GitHub.

github.com

https://github.com/VSFe/Algorithm_Study

 

GitHub - VSFe/Algorithm_Study: This repository consists of materials for those preparing for coding tests and algorithm intervie

This repository consists of materials for those preparing for coding tests and algorithm interviews. - GitHub - VSFe/Algorithm_Study: This repository consists of materials for those preparing for c...

github.com

 

'알고리즘 공부 > 파이썬 개념' 카테고리의 다른 글

코드업 6097번 문제  (0) 2022.01.26
코드업 100제 [파이썬] 51-100제  (0) 2022.01.24
코드업 100제 [파이썬] 1-50제  (0) 2022.01.23

스코프란?

참조 대상 식별자를 (identifier, 변수, 함수의 이름과 같이 어떤 대상과 구분하여 식별할 수 있는 유일한 이름) 찾아내기 위한 규칙.

식별자는 자신이 어디에 선언됐는지에 의해 자신의 유효한(다른 코드가 자신을 참조할 수 있는) 범위를 가진다.

 

스코프의 구분

전역 스코프 : 코드 어디에서든지 참조할 수 있다

지역 스코프 : 함수 코드 블록이 만든 스코프, 함수 자신과 하위 함수에서만 참조할 수 있다.

 

자바스크립트 스코프의 특징

자바스크립트는 타 언어와 달리 함수 레벨 스코프를 따른다. 

 

함수 레벨 스코프?

함수 코드 블록 내에서 선언된 매개변수와 변수는 코드 블록 내에서만 지역변수처럼 사용되고 함수 외부에서는 유효하지 않다

var a = 10;     // 전역변수

(function () {
  var b = 20;   // 지역변수
})();

console.log(a); // 10
console.log(b); // "b" is not defined

=> 변수 b는 지역변수이기 때문에 undefined가 출력된다.

 

함수 내 지역 영역에서는 전역과 지역 중 지역변수를 우선 참조한다

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x);
}

foo();          // local
console.log(x); // global

 

함수 영역 내에서 전역변수를 참조해서 전역변수의 값을 변경할 수도 있다

var x = 10;

function foo() {
  x = 100;
  console.log(x); //100
}
foo();
console.log(x); // 100

=> 전역변수의 값이 변경된 결과가 나온다

 

 

단, ECMAscript6에서 도입된 let, const 를 사용하면 블록 레벨 스코프를 사용할 수 있다.

 

블록 레벨 스코프?

코드 블록 ({...}) 내에서 유효한 스코프

함수내부에서만 유효했던 것과 비슷하게, 블록 안에서 선언하면 자신을 정의하는 블록과 하위 블록에서만 접근이 가능하다.

 

 

전역 스코프

전역에 변수를 선언하면 어디서든지 참조할 수 있는 전역 스코프를 가진 전역 변수가 된다.

-> 전역 객체(Global Object) window의 프로퍼티이다.

의도치 않은 재할당에 의한 상태 변화로 코드를 예측하기 어려워지므로 사용을 억제해야 한다.

 

 

렉시컬 스코프

렉시컬 스코프는 함수를 어디에 호출하는지가 아니라 어디에 선언하였는지에 따라 결정된다.

자바스크립트는 렉시컬 스코프를 따르므로 함수를 선언한 시점에 상위 스코프가 결정된다.

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // 1
bar(); // 1

=> bar()가 어디서 호출되었는지는 스코프 결정에 아무런 의미를 주지 않는다. bar는 전역에 선언되었기 때문에 

bar의 상위 스코프는 전역 스코프이고 전역 변수 x의 값 1을 두 번 출력하게 된다.

 

 

암묵적 전역(implicit global)

var x = 10; // 전역 변수

function foo () {
  // 선언하지 않은 식별자
  y = 20;
  console.log(x + y);
}

foo(); // 30

선언하지 않은 식별자에 값을 할당하면 전역객체의 프로퍼티가 된다.

y = 20 을 window.y = 20 으로 해석해서 y는 마치 전역 변수처럼 동작한다. 이러한 현상을 암묵적 전역이라고 한다.

// 전역 변수 x는 호이스팅이 발생한다.
console.log(x); // undefined
// 전역 변수가 아니라 단지 전역 프로퍼티인 y는 호이스팅이 발생하지 않는다.
console.log(y); // ReferenceError: y is not defined

var x = 10; // 전역 변수

function foo () {
  // 선언하지 않은 변수
  y = 20;
  console.log(x + y);
}

foo(); // 30

=> 단지 전역 객체의 프로퍼티로 추가되었을 뿐이기 때문에 변수가 아니다. 그러므로 변수 호이스팅은 발생하지 않는다.

 

 

스코프 체인

현재 스코프에서 식별자를 검색할 때 상위 스코프를 연쇄적으로 찾아나가는 방식을 말한다.

function a(){
     var a = 1;              
     function b(){
      	console.log(a);  
     }
     b();
}
a();

b() 함수 내에서 변수 a를 탐색하기 시작하는데,

만약 b() 함수에 변수 a가 없다면 함수 b()를 감싸고 있는 외부함수 a()를 탐색하게 된다.

이때 변수 a가 존재하면 a를 참조하게 되고 없다면 계속적으로 감싸고 있는 상위 함수를 탐색합니다.

결국 찾지 못하고 root인 Global Object 실행 컨텍스트까지 와서 a 가 없다면 VM500:1 Uncaught ReferenceError: a is not defined라는 에러를 출력한다.

함수가 생성(선언)될 때마다 렉시컬 환경이 만들어지고 그 안에 outer 참조값이 있다. 바로 이 outer 참조값이 상위 스코프의 렉시컬 환경을 가리키기 때문에 이를 통해 체인처럼 연결되는 것이다.

(= 함수가 생성되면 Execution Context가 생성되고, 그리하여 Lexical Environment 안의 outer Lexical Enviroment가 상위 Environment Record와 연결되면서 내부 함수 정보를 탐색할 수 있게 된다.)

 

즉, 내부 스코프에서 외부 스코프로 찾아가는 방식이다.

 

 

 

참고:

https://tyle.io/blog/54

https://poiemaweb.com/js-execution-context

https://github.com/baeharam/Must-Know-About-Frontend/blob/main/Notes/javascript/scope.md

 

'엘리스 ai 트랙 > FE' 카테고리의 다른 글

IIFE (즉시 호출 함수 표현식)  (0) 2022.02.28
var vs let vs const  (0) 2022.02.21
BFC (Block Formatting Context)  (0) 2022.02.05
z-index  (0) 2022.02.02
표준모드(standards mode)와 호환모드(quirks mode)  (0) 2022.01.23

https://www.acmicpc.net/problem/2358

 

2358번: 평행선

첫째 줄에 n(1 ≤ n ≤ 100,000)이 주어진다. 다음 n개의 줄에는 각 점의 좌표가 주어진다. 만약 입력에 서로 같은 두 점이 주어지면, 그 두 점을 이용하여 직선을 만들 수 있다. 좌표는 절댓값이 231보

www.acmicpc.net

원리.

x축에 평행하다 -> y좌표가 같다

y축에 평행하다 -> x좌표가 같다

 

 만약 입력에 서로 같은 두 점이 주어지면, 그 두 점을 이용하여 직선을 만들 수 있다.

(1, 0) 하나로도 직선을 만들 수 있고, (2, 0) 하나로도 직선을 만들 수 있고, (3, 0) 하나로도 직선을 만들 수 있다는 뜻이다.

하지만,

(1, 0) (2, 0) (3, 0)은 세개 다 y축에 평행하지만 같은 축으로 인식해야 한다.

즉, y = 0인 축 하나라고 인식해야 한다.

 

import sys

n = int(sys.stdin.readline())

dots = []
for _ in range(n):
  dot = tuple(map(int, sys.stdin.readline().split(' ')))
  dots.append(dot)

Xs = []
Ys = []
count = 0
for i in range(n):
  for k in range(i+1, n):
    if(dots[i][0] == dots[k][0]): #x좌표 같은지 확인 (y축에 평행)
      if not dots[i][0] in Xs: #같다면 중복되지 않도록
        Xs.append(dots[i][0])
        count += 1
      else:
        continue
    if(dots[i][1] == dots[k][1]): #y좌표 같은지 확인 (x축에 평행) 
      if not dots[i][1] in Ys: #같다면 중복되지 않도록
        Ys.append(dots[i][1])
        count += 1
      else:
        continue
    else:
      continue
print(Xs)
print(Ys)
print(count)

리스트 안에 튜플을 넣도록 해서 각 좌표마다 for문을 돌면서 같은 게 있는지 체크했다.

x좌표에서 같은 게 있다면 x좌표의 리스트(=Xs)에 보관해서 같은 축이라면 중복돼서 count되지 않도록 했다.

똑같이, y좌표에서 같은 게 있다면 y좌표의 리스트(=Ys)에 보관해서 같은 축이라면 중복돼서 count되지 않도록 했다.

 

이렇게 구현하니까 동작은 잘 되는 듯 했지만 시간 초과 오류가 난다....

 


 

그래서 딕셔너리, 집합, 튜플 등 여러 데이터타입으로 해봤지만 딕셔너리는 같은 key 값이면 value값을 이전 값을 지우고 새로운 값만을 덮어서 저장하고 집합은 중복해서 저장하지 않기 때문에 같은 축이었을 경우를 구분짓지 못했다... 그래서 이상하고 요상한 방법으로 시도해봤지만 다시 시간 초과 오류가 떴다.

 

그러다가 다른 블로그 글을 봤는데, 몰랐던 데이터타입을 발견할 수 있었다. 

defaultDict() 라는 유사딕셔너리 이다.

딕셔너리는 조작할 때 value값을 계속 바꾸게 된다.

defaultdict 생성

하지만 디폴트 딕셔너리의 경우에 value 값을 리스트나 정수, 집합으로 디폴트를 바꿀 수 있고,

리스트라면 리스트의 함수를 사용할 수 있게 한다.

이렇게 리스트의 함수인 append를 사용해서 넣으면 내가 원했던 것처럼 value가 여러개면 여러개가 하나의 key값에 다 들어가게 되는 걸 볼 수 있었다.

 

 

그런데 이렇게 값을 넣어버리면 할당으로 값이 변하게 되는 것이기 때문에 

이전의 값에 덮어씌워지는 문제가 발생한다.

 

 

 

collections로부터 defaultdict함수를 가져와서 defaultdict(list)로 생성을 하고,

리스트 함수에 하듯이 append()함수를 붙여서 추가해주면 key값이 같더라도 value가 덮어씌워지는 것이 아니라 리스트 형태로 차곡차곡 쌓일 수 있게 된다.!

그럼 이것을 활용해서 

 

x좌표를 key로 하고 y좌표를 value로 한 딕셔너리,

y좌표를 key로 하고 x좌표를 value로 한 딕셔너리

두개의 딕셔너리를 만든다.

그리고 각 key 값에 대해서 value값이 2개 이상이면 count 값을 증가시켜준다.

from collections import defaultdict
import sys

n = int(sys.stdin.readline())

#유사딕셔너리 사용 : dict 클래스의 서브 클래스
#딕셔너리의 value의 디폴트를 리스트로 생성함
xDots = defaultdict(list) #x가 key, y가 value 
yDots = defaultdict(list) #y가 key, x가 value

for i in range(n):
  x, y  = map(int, input().split(' '))
  xDots[x].append(y) #리스트 함수를 사용할 수 있게 됨
  yDots[y].append(x)

count = 0
for i in xDots.keys(): # y축 평행 => y값 같은 게 있다
  if(len(xDots[i]) >= 2): #하나의 key 값에 2개 이상의 value값이 있다면 증가시킴
    count+= 1

for i in yDots.keys():  # x축 평행 => y값 같은 게 있다
  if(len(yDots[i]) >= 2):
    count+= 1
print(xDots, yDots)
print(count)

 

참고: https://firsteast.tistory.com/126

 

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 11399 [ATM]  (0) 2022.05.18
백준 2217[로프]  (0) 2022.05.17
백준 2609 [최대공약수와 최소공배수]  (0) 2021.02.04
백준 11022 [A+B-8]  (0) 2021.02.04
백준 2747 [피보나치수]  (0) 2021.01.22

콜백함수? 다른 함수의 인자로 넘겨지는 함수.

매개변수로 받는 함수가 콜백함수.

익명함수로 즉석에서 만든 함수도 콜백함수.

 

1, 2, 4가 콜스택에 있다가 실행된 뒤에 3초뒤에 3이 콜스택으로 들어와서 실행됨. => 1, 2 4, (3초 뒤에) 3

 

콜백함수를 이용해서 동기적으로 코딩할 수 있음. => 1, 2, (2초 뒤에) 3, 4

함수를 인자처럼 사용하려고 콜백을 쓰는 것이라고도 생각하자.

 

callback.js promise.js 

 

Promise의 3가지 상태

: pending(준비), fulfilled(이행), rejected(거부)

Promise를 이행상태로 만들어야 then을 사용할 수 있는 것이다.

 

new Promise()가 처리하는 쪽 (되면 resolve, 안되면 reject)

.then()은 Promise가 resolve를 호출했기 때문에 then()으로 들어오는 것. 요청하는 쪽.

두 쪽 모두 성공하는 경우와 실패하는 경우가 있어야 함.

**fetch가 Promise이다.

 

만약에 함수의 매개변수와 return문의 함수에 쓰이는 매개변수가 같으면 함수만 작성해도 됨.

 

return과 break의 차이는?

return은 반복문을 종료시킬 수도 있지만 반복문을 감싸고 있는 함수가 있다면 함수 자체를 종료시킨다.

break는 반복문을 실행하다가 그 즉시 실행을 멈추고 반복문을 종료시킨다.

continue는 명령을 건너뛰고 다음 명령으로 이동한다.

'엘리스 ai 트랙 > 개인 공부' 카테고리의 다른 글

비동기 통신  (0) 2022.02.08
FormData, 복리계산기 (3주차)  (0) 2022.02.07
IIFE를 알아보다가..  (0) 2022.02.05
closure 공부하기  (0) 2022.01.28
Node 객체 공부 중에  (0) 2022.01.26

개발자 모드에서 네트워크에서 서버와 브라우저가 통신하고 있는 것을 볼 수 있다

네이버 검색창에 '새ㅇㅇ'을 검색하고 있을 때 네트워크 상황

 

이고잉님 강의자료

https://docs.google.com/document/d/1bzKpUgF2fTlo3wA-qxyfg1Mqi6A5O9LhQDY-0JlXpGQ/edit#

 

json-server 레포지토리 사이트

https://github.com/typicode/json-server

 

fetch() cheetSheet

https://devhints.io/js-fetch

 

Json placeholder

https://jsonplaceholder.typicode.com/guide/

 

JSON.stringify()는 json으로 인코딩한 것이고 (객체 타입 -> 텍스트로 전환)

JSON.parse()는 원래 데이터 타입으로 디코딩한 것입니다. (텍스트 -> 객체로 전환)

 

JSON을 만든 사람의 사이트 주소?

https://json.org/json-ko.html

 

웹브라우저가 서버에게 이 데이터 타입은 JSON이라고 알려줄 때 사용하는 것?

'Content-Type': 'application/json',

 

rest API

resource
method: POST
method: GET

데이터가 resource , 그 데이터를 수정하는 방법들이 method (디폴트는 GET)

element

데이터 중에 특정한 데이터 하나를 가지고 오고 싶다면 그 한 건은 element

 

함수는 1급식이지만 if문은 2급식

setTimeout(function() { alert(1); }, 1000)

함수의 인자로 전달된 함수 : 콜백함수

 

fetch API 

내가 사용하는 함수의 리턴값이 Promise라면?

  1. promise는 then을 호출하면 된다.
  2. 이 then에는 함수를 넣어주면 된다. (=콜백함수)
  3. 그 함수는 이 작업이 성공했을 때 호출될 것이다
  4. 그 함수의 첫번째 파라미터엔 데이터가 들어가 있다.
  5. then은 두개의 파라미터가 있다. 
  6. 첫번째 파라미터는 성공할 때 실행되고, 두번째 파라미터는 실패할 때 실행될 것이다.
  7. 두번째 함수의 첫번째 파라미터에는 실패한 이유가 들어있을 것이다.

 

여기서 data는 response 객체이다. 서버가 응답한 정보들이 다 정리정돈돼서 우리에게 오는 것이다,

이 data를 JSON객체로 컨버팅해서 받고 싶다. -> 그러면 리턴한 값이 Promise이다

위의 코드랑 같은 코드임. promise를 그대로 return해주면 바로 뒤에 .then()을 해줄 수가 있다.

data.json도 비동기 작업, promise 작업이 이루어지고 then을 호출하는 것이다.

 

그런데, 너무 Promise로 리턴을 하게되면 then hell promise 현상이 발생할 수 있다.

 

생활코딩 promise 수업

https://www.youtube.com/watch?v=Sn0ublt7CWM 

생활코딩님 강의트리인 서말을 자주 이용하자...!!!!!!!!!!!!!!

https://opentutorials.org/course/3083

https://seomal.org/

 

'엘리스 ai 트랙 > 개인 공부' 카테고리의 다른 글

callback vs promise  (0) 2022.02.08
FormData, 복리계산기 (3주차)  (0) 2022.02.07
IIFE를 알아보다가..  (0) 2022.02.05
closure 공부하기  (0) 2022.01.28
Node 객체 공부 중에  (0) 2022.01.26

FormData?

form 필드와 그 값을 나타내는 일련의 key/value 쌍을 쉽게 생성할 수 있는 방법을 제공함.

FormData를 구현하는 객체는 entries()대신 for..of 구조를 직접 사용할 수 있다.

 

생성자: FormData()

for of 반복문으로 formData의 내부를 확인해보니까 각 요소들이 배열의 형태로 k-v쌍으로 들어가 있는 걸 확인할 수 있었다. formData 자체는 반복가능한 객체이다.

참고: for..of 명령문은 반복가능한 객체에 대해서 개별 속성값에 대해서 반복함.

 

참고: https://developer.mozilla.org/ko/docs/Web/API/FormData

 

FormData - Web API | MDN

FormData 인터페이스는 form 필드와 그 값을 나타내는 일련의 key/value 쌍을 쉽게 생성할 수 있는 방법을 제공합니다. 또한 XMLHttpRequest.send() (en-US) 메서드를 사용하여 쉽게 전송할 수 있습니다. 인코

developer.mozilla.org


 

formData객체를 key-value쌍을 이루는 하나의 객체로 만들기. (더이상 반복가능한 객체가 아님) 

 

Array.from() ?
유사배열 객체나 반복가능한 객체를 얕게 복사해 새로운 Array 객체를 만듬

 

formData.entries() ?

객체에 포함된 모든 k-v쌍을 통과하는 iterator를 반환.

 

참고: https://developer.mozilla.org/ko/docs/Web/API/FormData/entries

 

 


저 코드 상에서 Array.from을 사용하지 않으면 에러가 나오는데 그 이유는 뭘까?

?

formData.entries()를 할 때 그것은 구조상 array 같아보이지만 사실 그렇지 않다.

=> 유사배열로 이해하면 될 것 같다

 

NodeList 유형의 프로토타입을 보면 reduce 메서드가 없다는 걸 알 수 있다. 그래서 Array.from으로 전달해준다면 적절한 배열로 반환되고 reduce, map, 등 기타 배열관련 함수를 사용할 수 있게 된다!!

참고: https://stackoverflow.com/questions/38598801/map-reduce-is-not-a-function/38598861

 

유사배열이란?

DOM type은 배열처럼 보이지만 타입은 object이고 심지어 배열과 비교해보면 false가 출력된다.

 

 

배열이 아닌데 배열인 척 하는 것을 유사배열 혹은 유사배열 객체라고 부른다.

선언은 객체처럼 하고 반드시 length를 가져야 한다는 특징이 있다.

 

참고:https://kamang-it.tistory.com/entry/JavaScript15%EC%9C%A0%EC%82%AC%EB%B0%B0%EC%97%B4-%EA%B0%9D%EC%B2%B4Arraylike-Objects

 

 


formData = {principal: 1, rate: 2, year: 3, frequency: 1}
const {principal, rate, year, frequency} = formData
{
        principal : Number(principal),
        rate: Number((rate / 100).toFixed(2)),
        year: Number(year),
        frequency: Number(frequency)
 }

객체로부터 key 값을 한번에 가져와서 각 value 값을 한번에 바꿔줄 수 있다

 

 

'엘리스 ai 트랙 > 개인 공부' 카테고리의 다른 글

callback vs promise  (0) 2022.02.08
비동기 통신  (0) 2022.02.08
IIFE를 알아보다가..  (0) 2022.02.05
closure 공부하기  (0) 2022.01.28
Node 객체 공부 중에  (0) 2022.01.26

IIFE?

즉시 호출 함수 표현식.

주로 이름 충돌 최소화 및 private 변수 생성에 사용되는 자바스크립트 디자인 패턴 이다.

참고 사이트 : https://velog.io/@bisu8018/JS-IIFEImmediately-Invoked-Function-Expressions-%EB%9E%80

 //함수 단축 표현식으로 함수 리터럴을 사용하는데
  const time = function ()  {
    let min = 60;
    let hour = min * 60
    let day = hour * 24
    let week = day * 7
    let month = week * 4
    let year = month * 12
    
    return {min, hour, day, week, month, year};
}

console.log(time) //실행을 할 때 func로 만 출력하면 그 함수의 순수 코드내용이 보이게 된다.
// ƒ ()  {
//     let min = 60;
//     let hour = min * 60
//     let day = hour * 24
//     let week = day * 7
//     let month = week * 4
//     let year = month * 12
    
//     return {min, hour, day, week, month, year};
// }
console.log(time()) //실행을 할 때 func()로 출력해야 그 함수가 실제로 동작된 내용을 볼 수 있다.

IIFE (즉시 호출 함수 표현식)을 접했는데 이 표현식을 사용하지 않고 함수를 사용하는 방법엔 어떤 것이 있을지 뚱땅대다가 함수 단축표현식으로 함수리터럴을 만들었을 때의 사용법을 알게 됐다!

 

IIFE로는 time 상수를 선언한 마지막에 함수 호출 기호인 ()를 추가해주면 된다.

 

즉시 실행 함수는 그 즉시 실행된 뒤에 전역에서 사라진다. -> 전역변수 사용을 억제해준다

'엘리스 ai 트랙 > 개인 공부' 카테고리의 다른 글

비동기 통신  (0) 2022.02.08
FormData, 복리계산기 (3주차)  (0) 2022.02.07
closure 공부하기  (0) 2022.01.28
Node 객체 공부 중에  (0) 2022.01.26
git push 오류  (0) 2022.01.19

Block Formatting Context? (블록 형식 지정 컨텍스트)

웹페이지의 블록 레벨 요소를 렌더링하는 데 사용되는 CSS의 비주얼 서식 모델 중 하나.

=> 웹 페이지를 렌더링하는 시각적인 CSS의 일부로서 블록 박스의 레이아웃이 발생하는 지점과 floating 요소의 상호작용 범위를 결정하는 범위라고 볼 수 있습니다.

다음 조건 중 하나만 만족한다면 새로운 BFC를 생성할 수 있습니다

  • 루트 혹은 이를 포함하는 요소
  • float가 none이 아니면서 clear 되지 않은 경우
  • position이 absolute / fixed
  • display가 inline-block / tabel-cell / tabel-caption
  • overflow가 visible이 아님
  • display가 flex / inline-flex

잠깐 설명드리자면..!

더보기

overflow: hidden //부모요소의 범위를 넘어가는 자식요소의 부분은 보이지 않도록 처리

float: left //요소를 왼쪽으로 밀고 다른 요소가 주위를 둘러싸게 함

활용

1. 마진겹침 제거하기

https://codepen.io/BaeHaram/pen/YzXGZBd

마진 상쇄 제거효과
마진 상쇄? 요소의 margin 값이 겹칠 경우, 더 큰 margin만 적용되고 같다면 한 번만 적용되는 현상

마진 상쇄라는 특성 때문에 top 과 bottom에 각각 마진을 부여했지만 마진끼리 겹쳐서 10px만큼의 마진만 생기게 된다
=> BFC를 적용시키면 마진 상쇄효과가 없어지게 돼서 총 20px만큼의 마진이 생길 수 있다!

2. 부모가 자식을 모두 담지 못하는 경우 (float 사용)

https://codepen.io/BaeHaram/pen/oNXZBXJ

BFC 생성 전

BFC 생성 후

float을 사용하고 부모가 자식을 담지 못하는 경우에 BFC를 생성하게 해주는 코드를 넣으면 컨테이너가 담지 못했던 float을 담게 되고 float 크기만큼 커지게 됩니다!

float된 요소를 포함하는 컨테이너가 있는 경우가 많을 수 있는데 이 경우엔 보통 container를 clear시키는 방법을 사용합니다. 그런데 그것 말고도 BFC를 정의함으로써도 이것을 해결할 수 있는 것입니다!
=> float을 clear 시키는 다양한 방법 중에 여러가지가 있을 수 있는데 overfloe: hidden이 BFC를 생성하게 한 것입니다. 그래서 BFC는 float과의 상호작용에 영향을 미쳐서 float를 clear시키는 효과를 가져옵니다

BFC는 레이아웃 안의 작은 레이아웃이라고 생각하기
=> BFC 내부의 모든 요소는 설령 내부 요소가 float 상태라 하더라도 이 블록 안에 속한다. 그래서 float요소는 container 높이에 영향을 주게 된다.

3. float된 요소를 감싸는 텍스트를 분리하기

https://codepen.io/BaeHaram/pen/VwLpPvN

BFC 전(Figure 1) BFC 생성 후 (Figure 2)

Figure 1
p태그의 블록상자가 float 요소를 위한 공간을 만들기 위해 수평으로 좁아지게 됩니다.

BFC에서 각 상자의 왼쪽 가장자리는 container 블록의 왼쪽 가장자리에 닿게 됩니다. 그래서 새로운 BFC를 생성하지 않는다면 p태그의 텍스트가 증가한다면 float 요소 밑으로 이동될 것입니다.

In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
참고: WSC

전체 요소를 이동할 수 있다면 이 감싸지는 문제는 해결될 것입니다.

Figure 2
p태그에 새로운 BFC를 생성하기!
=> 더이상 container 박스의 왼쪽 가장자리로 닿게 되는 문제가 사라지게 되므로 간단하게 감싸는 문제를 해결할 수 있게 됩니다!



출처:
https://www.sitepoint.com/understanding-block-formatting-contexts-in-css/
https://www.w3.org/TR/CSS21/visuren.html#block-formatting
https://tesseractjh.tistory.com/m/145
https://velog.io/@seod0209/TIL-14.-overflow
https://velog.io/@1-blue/%EB%B8%94%EB%A1%9D-%EC%84%9C%EC%8B%9D-%EB%A7%A5%EB%9D%BD

'엘리스 ai 트랙 > FE' 카테고리의 다른 글

var vs let vs const  (0) 2022.02.21
스코프  (0) 2022.02.14
z-index  (0) 2022.02.02
표준모드(standards mode)와 호환모드(quirks mode)  (0) 2022.01.23
사용할 링크 모음!  (0) 2022.01.23

+ Recent posts