1. 메소드 안 : 메소드를 소유한 object

this : object person

1
2
3
4
5
6
7
8
var person = {
  firstName: "John",
  lastName : "Doe",
  id     : 5566,
  fullName : function() {
    return this.firstName + " " + this.lastName;
  }
};
cs

 

2. alone(어디에도 속하지 않을 때?) : 전역 객체 (window)

1
2
3
4
<script>
var x = this;
document.getElementById("demo").innerHTML = x;
</script>
cs

 

3. 함수 안 : 전역 객체 (window)

1
2
3
4
5
6
<script>
document.getElementById("demo").innerHTML = myFunction();
function myFunction() {
  return this;
}
</script>
cs

 

4. 함수 안 (strict mode) : undefined

1
2
3
4
5
6
7
<script>
"use strict";
document.getElementById("demo").innerHTML = myFunction();
function myFunction() {
  return this;
}
</script>
cs

 

5. event 안 : event를 받는 element

this : button

1
2
<button onclick="this.style.display='none'">Click to Remove Me!</button>
 
cs

 

6. call(), apply() :  any object (그 어떤 객체도 의미 가능)

1
2
3
4
5
6
7
8
9
10
11
var person1 = {
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
}
var person2 = {
  firstName:"John",
  lastName: "Doe",
}
var x = person1.fullName.call(person2); 
document.getElementById("demo").innerHTML = x; 
cs

call(), apply() : https://www.zerocho.com/category/JavaScript/post/57433645a48729787807c3fd

 

출처 : https://www.w3schools.com/js/js_this.asp

 

 

 

반응형

[ON vs WHERE]

ON : JOIN 을 하기 전 필터링을 한다 (=ON 조건으로 필터링이 된 레코들간 JOIN이 이뤄진다)

WHERE : JOIN 을 한 후 필터링을 한다 (=JOIN을 한 결과에서 WHERE 조건절로 필터링이 이뤄진다)

 

[INNER JOIN 에서의 ON vs WHERE]

1. INNER JOIN + ON 조건절 + ON 조건절

1
2
3
4
5
SELECT *
FROM a
INNER JOIN b
ON a.key = b.key
AND a.key2 = b.key2
cs

2. EQUI JOIN + WHERE 조건절

1
2
3
4
SELECT *
FROM a AS a , b AS b
WHERE a.key = b.key
AND a.key2 = b.key2
cs

3. INNER JOIN + ON 조건절 + WHERE 조건절

1
2
3
4
5
SELECT *
FROM a
INNER JOIN b
ON a.key = b.key
WHERE a.key2 = b.key2
cs

위 세 쿼리는 모두 같은 결과, 같은 퍼포먼스가 나온다.

즉, inner join 에서의 on 조건과 where 조건은 같다.

https://stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause

 

[그래도 EQUI JOIN 보단 INNER JOIN 을 써야 하는 이유]

1. 가독성

2. OUTER JOIN 으로 수정이 용이

 

[OUTER JOIN 에서의 ON vs WHERE]

1. OUTER JOIN 정리 (출처)

 

2. OUTER JOIN 에서의 ON vs WHERE

1) OUTER JOIN test 를 위한 샘플 준비.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 샘플 테이블 생성
create table table1 (
  col1 INT,
  col2 VARCHAR(10)
);
create table table2 (
  col1 INT,
  col2 VARCHAR(10)
);
commit;
 
-- 샘플 데이터 입력
insert into table1 (col1, col2) values (1'하나');
insert into table1 (col1, col2) values (2'둘');
insert into table1 (col1, col2) values (3'셋');
 
insert into table2 (col1, col2) values (1'일');
insert into table2 (col1, col2) values (2'이');
commit;
cs

2) 데이터 확인

table1 :

col1 col2
1 하나
2
3

table2 :

col1 col2
1
2

 

3) OUTER JOIN 에서의 ON

1
2
3
4
5
SELECT t1.col1, t1.col2, t2.col1, t2.col2
FROM   table1 t1
LEFT OUTER JOIN table2 t2
ON t1.col1 = t2.col1
AND t2.col2 = '일';
cs

위 쿼리의 결과 :

t1.col1 t1.col2 t2.col1 t2.col2
1 하나 1
2 null null
3 null null

>> table1의 전체 row와 

     table2에서 col2 칼럼 값이 '일'인 로우만 뽑은 row 들을 OUTER JOIN.

>> on 조건은 join 을 하기 전에 필터링 되는 기준

 

4) OUTER JOIN 에서의 WHERE (위 쿼리의 ON 조건을 WHERE 에 그대로 추가)

1
2
3
4
5
select t1.col1, t1.col2, t2.col1, t2.col2
from  table1 t1
LEFT OUTER JOIN table2 t2
ON t1.col1 = t2.col1
where t2.col2 = '일';
cs

위 쿼리의 결과

t1.col1 t1.col2 t2.col1 t2.col2
1 하나 1

>> table1의 전체 row와

     table2 전체 row 를 OUTER JOIN 한 후,

     col2 칼럼 값이 '일'인 로우만 뽑는다.

>> WHERE 조건은 JOIN을 한 이후에 필터링하는 기준

 

반응형

[scope란?]

참조대상 식별자를 찾아내기 위한 규칙.

특정 변수가 선언되어 있을 때, 해당 변수를 소스 내 어디에서 찾아서 사용할 지를 규정하는 규칙.

 

[전역스코프 vs 지역스코프]

전역스코프 : 코드 내 모든 곳에서 참조 가능.

지역스코프 : 함수 코드 블록 내에서 만들어진 스코프로 함수 자기 자신과 하위 함수에서만 참조 할 수 있다.

※ 최상위 스코프는 window

 

[블록레벨스코프 vs 함수레벨스코프]

블록레벨스코프 block-level scope : if문, for문 과 같은 블록 내에 선언된 변수는 블록 밖에서는 참조가 불가하다. (대부분의 C언어, 자바언어)

함수레벨스코프 function-level-scope : 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 참조가 가능하다. (ECMAScript 6 부터 도입된 let 키워드 사용시 블록 레벨 스코프 사용 가능)

1
2
3
4
5
6
function sample(){
    if(true) {
        var tt = 1;
    }
    console.log(tt);
}
cs

>> javascript 는 함수레벨 스코프이므로, 함수 블록 내에서 선언된 변수는 함수 블록 내에서 참조가 가능. 싱기방기

1
2
3
4
5
6
function sample(){
    if(true) {
        let tt = 1;
    }
    console.log(tt);
}
cs

>> 블록레벨스코프 변수 let 을 사용했으므로 5번라인에서 tt 사용시 에러를 뱉음(java 및 기타 C계열언어와 같이 동작)

 

[동적스코프 vs 렉시컬스코프]

동적스코프 dynamic scope : 호출 시점에 따라 상위 스코프 결정

렉시컬스코프 lexical scope : 함수 선언 위치에 따라 상위 스코프 결정 (js 를 포함한 대부분의 언어가 해당 스코프를 따름)

1
2
3
4
5
6
7
8
9
10
var x = 1;
function foo() {
  var x = 10;
  bar();
}
function bar() {
  console.log(x);
}
foo(); // ?
bar(); // ?
cs

위와 같을 때, 결과는 1출력.

>> javascript 는 렉시컬 스코프를 따르므로 bar가 선언된 위치에 따라 상위 스코프가 결정되며, bar 내의 x 는 bar 의 상위 스코프 내에서 찾게된 전역 변수 x = 1 을 사용

※ 동적스코프 : bar의 상위 스코프는 함수 foo와 전역, 결과 10 출력

렉시컬스코프 : bar의 상위 스코프는 전역, 결과 1 출력

 

추가 예)

window.location.protocol 은 현재 페이지의 protocol (http: or https:) 을 뽑아낼 때 사용가능한 내장함수.

window 를 빼고, location.protocol 까지만 써줘도 window.location.protocol 을 가져올 수 있다.

스코프를 상위로 옮겨가며 탐색하다 계속 찾지 못한다면  window 까지 올라가서 찾아오기 때문.

 

그렇다면 protocol만 써줄 경우 이 케이스는 왜 못찾고 에러를 뱉는가?

> protocol은 window가 아닌 window.location 내에 존재.

> 현재 스코프 내에서 protocol 을 찾지 못한다면 상위 스코프에서 찾기 시작하고 결론적으론 window 까지 올라가서 찾게 될 뿐 window.location 내에서 찾진 않기 때문.

 

 

참고 : https://poiemaweb.com/js-scope

매우 좋은 블로그를 찾았다. 유레카..

반응형

javascript 에서 hoisting 이란 단어 뜻 그대로 끌어올리기라는 의미로써, 변수를 최상단으로 끌어올리는 것을 뜻한다.

이와 같은 자바스크립트에서의 호이스팅이란 특징으로 인해, 

javascript에서 변수는 사용된 이후 선언 될 수 있다. (==변수를 사용한 후 선언 할 수 있다)

 

[case 1]

1
2
3
4
5
$(document).ready(function(){
    var x;
    x = 5;
    console.log(x);
});
cs

변수를 선언 후 변수에 값을 저장한 케이스. 보기에도 문제가 없어보이고 실행 결과도 문제가 없다.

[case 2]

1
2
3
4
5
$(document).ready(function(){
    x = 5;
    console.log(x);
    var x;
});
cs

변수에 값을 저장/사용 후 선언한 케이스

java 같으면 케이스2에서 Exception 을 뱉겠지만, javascript 는 결과 5를 정상적으로 console 에 출력한다.

보기엔 에러가 발생할 것으로 보였던 코드임에도 에러없이 정상 결과가 나온 이유는 바로 hoisting 때문이다.

(var x; 부분(변수 선언부)을 현재 scope에서 최상단으로 끌어올렸기 때문)

(스코프와 관련된 내용은 여기를 참고)

 

그렇다면 호이스팅은 항상 이뤄질까?

자바스크립트는 선언부만 hoisting 할 뿐, 초기화 부분까지 호이스팅하지 않는다.

[case 3]

1
2
3
4
5
$(document).ready(function(){
    console.log(x);
    console.log(y);
    var x = 5;
});
cs

 

위 샘플 소스의 결과는 아래와 같다.

x 는 'undefined'를 콘솔에 출력하고 있고,

y 는 undefined Error 을 던지고 있다.

var x 부분은 hoisting 되었지만 초기화(=5)부분은 호이스팅되지 않았기 때문이다.

y는 스코프내에 선언되어 있지 않으므로 Error 를 뱉고 있다.

[결론]

예상치 못한 hoisting 동작으로 인한 에러를 피하기 위해 변수 선언 및 초기화는 최상단에서 해주자.

 

 

참고 : https://www.w3schools.com/js/js_hoisting.asp

 

 

반응형

[이직/면접 관련]

https://perfectacle.github.io/2019/08/23/exit-yanolja-feat-leisureq/#more

 

https://zorba91.tistory.com/270?category=876991

 

http://blog.naver.com/PostView.nhn?blogId=gngh0101&logNo=221296037812&parentCategoryNo=&categoryNo=38&viewDate=&isShowPopularPosts=true&from=search

 

채용공고: https://github.com/jojoldu/junior-recruit-scheduler

 

[면접질문 모음]

https://github.com/wayhome25/Interview_Question_for_Beginner

 

[개발관련]

back 개념정리가 잘 되어 있는 곳 : https://mangkyu.tistory.com/category

front 언어 정리가 매우 잘되어있는 곳 : https://poiemaweb.com/

탈휴먼 조대협님 블로그 : https://bcho.tistory.com/

전공 지식 정리가 잘 되어 있는 곳 : https://wayhome25.github.io/cs/2017/04/20/cs-26-bigO/

github 관련 설명 : https://milooy.wordpress.com/2017/06/21/working-together-with-github-tutorial/

클로저 간단하고 쉬운 설명 : https://yuja-kong.tistory.com/68?category=801961

반응형

typeof 는 js에서 타입을 반환하는 연산자(operator)로써 변수의 타입을 확인할 때 사용한다.

 

typeof 로 아래와 같이 number, string, object, boolean, function 타입을 확인 할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
console.log(typeof 123);              //number
console.log(typeof "str");             //string
console.log(typeof new Object());      //object
console.log(typeof {test : "test"});   //object
console.log(typeof true);              //boolean
console.log(typeof Symbol());          //symbol
console.log(typeof function(){});      //function
 
console.log(typeof 123 === 'number');               //true
console.log(typeof "str" === 'string');             //true
console.log(typeof new Object() === 'object');      //true
console.log(typeof {test : "test"=== 'object');   //true
console.log(typeof true === 'boolean');             //true
console.log(typeof Symbol() === 'symbol');          //true
console.log(typeof function(){} === 'function');    //true
cs

 

다음과 같은 타입은 주의하여 사용하자.

1
2
3
4
5
6
7
8
console.log(typeof null);                    //object
console.log(typeof new Object(123));        //object
console.log(typeof new Object("123"));        //object
        
console.log(typeof null === 'undefined');                //false
console.log(typeof new Object(123=== 'object');        //true
console.log(typeof new Object(123=== 'number');        //false
console.log(typeof new Object("123"=== 'string');        //false
cs

1. null 은 object (null 은 != null 과 같이 체크 할 것)

2. Object에 담긴 number/string 는 object

 

undefined : 선언은 되어있으나 아무 값도 저장되어 있지 않은 경우

undeclared : 변수 선언 자체가 되어 있지 않은 경우

* undefined , undeclared 모두 typeof 시 undefined로 반환

 

 

참고 : 

typeof document

정리가 잘 되어있는 글 (영어)

정리가 매우 잘 되어있는 글(한글)

반응형

javascript 에서 함수는 1급객체이다.

javascript 에서 함수는 아래와 같은 특징을 지닌다.

 

1. 익명함수로 작성 가능

2. 리턴값으로 사용 가능

3. 매개변수로 사용 가능

4. 변수, 자료구조로 저장 가능

 

위와 같은 특징으로 인해 callback 함수 같은 개..념이 존재.

 

[함수 선언식 vs 함수 표현식]

함수 선언식 : function func(){}

함수 표현식 : var func = function(){}

 

함수선언식으로 소스를 작성해도, 해당 소스 구동시 js 엔진 내에서 함수선언식을 함수표현식으로 바꾼다.

반응형

SYSDATE() : SYSDATE() 함수가 호출된 시각

NOW() : NOW() 가 포함된 쿼리(구문(statement))가 호출된 시각

 

[Ex]

1
2
3
4
5
6
7
SELECT
        SYSDATE(), 
        SLEEP(3) AS 'sleep'
        SYSDATE(),
        NOW(), 
        SLEEP(3) AS 'sleep'
        NOW();
cs

 

[결과]

 

[쿼리 한 줄씩 해석]

SELECT

SYSDATE() 함수 호출될 때의 시각 (6:52:28)

SLEEP(3)    3초간 Thread sleep (6:52:31)

SYSDATE() 함수 호출될 때의 시각 (6:52:31)

NOW()       쿼리(구문)가 실행될 때의 시각(6:52:28)

SLEEP(3)    3초간 Thread sleep (6:52:34)

NOW()      쿼리(구문)가 실행될 때의 시각(6:52:28)

 

※ SYSDATE와 NOW 는 각각 언제 사용해야 하는가?

- 실행결과에 따른 시각이 중요, 이를 저장해야하는 경우 NOW 사용

- 호출된 시각이 중요한 경우 SYSDATE 사용

ex) Spring Batch/Spring Quartz의 경우 Schedule, Job의 실행시각들이 메타테이블에 의해 관리가 되는데(Schedule, Job 관리가 inMemory 방식이 아닌 jdbc 방식인 경우), 쿼리가 끝난 시각이 아닌 호출시점의 시각이 중요하므로 SYSDATE를 사용하여 관리되고 있다.

 

참고 : https://database.guide/sysdate-vs-now-in-mysql-whats-the-difference/

반응형

유저가 페이지를 벗어날 때마다, 특정 처리를 해줘야 하는 상황엔 beforeunload 를 사용.

유저가 페이지를 벗어날 때 처리해 줄 코드와 함께 beforeunload event를 리스너에 등록하여 사용.

※ 뒤로가기, refresh 뿐만 아닌 submit, 브라우저 close 경우에도 beforeunload 리스너가 동작하게 되므로 주의.

 

[ Sample ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(window).on("beforeunload", callback);
 
function callback(){
    console.log("beforeunload callback !");
    //do something
    return "changes will be lost!";
}
 
function off(){
    console.log("beforeunload turn off !");
    $(window).off("beforeunload");
}
 
<button type="button" onclick="javascript:off();">리스너끄기</button>
cs

 

submit 을 제외한 모든 페이지 전환에 특정 함수를 실행시키고 싶은 경우 :

.off("~") 를 사용하여 submit 시엔 beforeunload 이벤트 핸들러를 제거.

 

[ Example ]

1
2
3
4
5
6
7
8
9
10
11
12
$(document).ready(function () {
    // Warning
    $(window).on('beforeunload'function(){
        //do something
        return "Any changes will be lost";
    });
    // Form Submit
    $(document).on("submit""form"function(event){
        // disable warning
        $(window).off('beforeunload');
    });
}
cs

 

 

반응형

1. 유저가 올린 파일의 이름을 그대로 사용하는 경우 (파일명을 바꿔줄 필요가 없는 경우)

1
formData.append('userpic', myFileInput.files[0]);
cs

2. 유저가 올린 파일의 이름을 바꿔서 파일명 중복을 회피하여 사용해야 하는 경우 (파일명을 바꿔줘야 하는 경우)

3번째 인자로 바꿀 파일명을 넣어준다.

1
formData.append('userpic', myFileInput.files[0], 'changeFileNm.jpg');
cs

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

 

[ UUID 생성 함수 ]

UUID.확장자 형태로 리턴

1
2
3
4
5
6
function makeUUID(file_nm){
   function s4() {
     return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
   }
   return s4() + s4() + s4() + s4() + s4() + s4() + s4() + s4() + file_nm.substr(file_nm.indexOf("."), file_nm.length-1);
}
cs

위 함수를 아래와 같이 사용.

1
formData.append('userpic', myFileInput.files[0], makeUUID(myFileInput.files[0].name));
cs

 

※ http FIleupload 는 여기를 참고

 

반응형

+ Recent posts