1. JavaScript에서의 this

JavaScript에서 함수의 this키워드는 다른 언어와 조금 다르게 동작합니다.
일반 함수의 this는 함수를 호출한 방법이 결정합니다. (동적 스코프 = Dynamic scope)
ES5에서 함수를 어떻게 호출했는지 상관하지 않고 this값을 설정할 수 있는 bind 메서드가 도입됐습니다.
ES6에서는 this 바인딩을 제공하지 않는 화살표 함수를 추가됐습니다.

화살표 함수에서 this는 항상 상위 스코프의 this를 가리킵니다. (정적 스코프 = Lexical scope = Static scope)

 

 

2. 일반 함수의 this

var person = {
  age: 27,
  getAge: function() {
    console.log(this); //{age: 27, getAge: ƒ}
    setTimeout(function() {
    	console.log(this); //Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
    }, 1000)
  }
}

person.getAge();

6번 라인의 this도 person을 가리킬 것 같지만 콜백 함수 내부의 this는 전역 객체 Window를 가리킵니다.

 

 

3. 일반 함수의 bind

var person = {
  age: 27,
  getAge: function() {
    console.log(this); //{age: 27, getAge: ƒ}
    setTimeout(function() {
    	console.log(this); //{age: 27, getAge: ƒ}
    }.bind(this), 1000)
  }
}

person.getAge();

6번 라인의 this가 person을 가리키게 하려면 7번 라인에서 this를 바인드시켜야 합니다.

이때 바인드 되는 this는 setTimeout함수 밖에 있으므로 4번 라인의 this와 동일합니다.

 

 

4. 화살표 함수의 this

var person = {
  age: 27,
  getAge: () => {
    console.log(this); //Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
    setTimeout(() => {
    	console.log(this); //Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
    }, 1000)
  }
}

person.getAge();

화살표 함수에서는 this 바인딩을 제공하지 않으므로

4번 라인의 this와 6번 라인의 this가 모두 전역 객체 Window를 가리킵니다.

 

var person = {
  age: 27,
  getAge: function() {
    console.log(this); //{age: 27, getAge: ƒ}
    setTimeout(() => {
    	console.log(this); //{age: 27, getAge: ƒ}
    }, 1000)
  }
}

person.getAge();

화살표 함수의 this는 항상 상위 스코프의 this를 가리키므로 6번 라인의 this는 4번 라인의 this와 동일합니다.

 

 

5. 참고 자료

 

this

JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작합니다. 또한 엄격 모드와 비엄격 모드에서도 일부 차이가 있습니다.

developer.mozilla.org

 

Function.prototype.bind()

bind() 메서드는 새로운 함수를 생성합니다. bind() 가 호출된 함수의 this 키워드를 주어진 값으로 설정하고, 새로운 함수의 인수(argument) 앞에 지정한 인수 시퀀스가 사용됩니다.

developer.mozilla.org

 

화살표 함수

화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고  자신의 this, arguments, super 또는 new.target을 바인딩 하지 않습니다. 화살표 함수는 항상 익명입니다. 이  함수 표현은 메소드 함수가 아닌 곳에 가장 적합합니다. 그래서 생성자로서 사용할 수 없습니다.

developer.mozilla.org

 

1. Ajax란?

Asynchronous JavaScript and XML의 약자로, 페이지 새로고침 없이 JavaScript로 서버에 정보를 요청해서 받은 후 일부만 로드할 수 있게 하는 기법이다.

 

 

2. 예제 설명

XMLHttpRequest Ajax 버튼을 클릭하면, XMLHttpRequest을 이용해서 데이터를 주고받고,

jQuery Ajax 버튼을 클릭하면, jQuery의 $.ajax()를 이용해서 데이터를 주고받는 예제입니다.

서버 쪽은 Spring의 @RestController를 사용했습니다.

 

 

3. HTML 코드

<h3>XMLHttpRequest/jQuery Ajax</h3>
<button id="btnXMLHttpRequest">XMLHttpRequest Ajax</button>
<button id="btnjQuery">jQuery Ajax</button>
<div id="divAjax" style="width: 250px; height: 50px; margin-top: 5px; border: 1px solid black"></div>

예제의 결과를 확인하기 위한 간단한 HTML 코드입니다.

 

 

4-1. XMLHttpRequest 코드

var btn = document.querySelector("#btnXMLHttpRequest");
btn.addEventListener('click', function(){
	
	var oReq = new XMLHttpRequest();
	oReq.addEventListener("load", function () {
		var data = JSON.parse(oReq.responseText);
		var div = document.querySelector("#divAjax");
		div.innerHTML = data.result;			

	});
	oReq.open("GET", "<%=request.getContextPath()%>/ajax?type=XMLHttpRequest");
	oReq.send();
	
});

XMLHttpRequest를 이용해서 /ajax에 type=XMLHttpRequest 파라미터를 GET방식으로 보낸 후, 받은 데이터를 divAjax에 표시합니다.

 

 

4-2. $.ajax() 코드

$("#btnjQuery").click(function(){

	$.ajax({
		url : "<%=request.getContextPath()%>/ajax",
		data : "type=jQuery",
		type : "GET",
		success : function(data){
			$("#divAjax").html(data.result);
		}
	});
	
});

$.ajax()를 이용해서 /ajax에 type=jQuery 파라미터를 GET방식으로 보낸 후, 받은 데이터를 divAjax에 표시합니다.

4-1과 4-2의 코드는 같은 기능을 다른 방법을 이용해서 구현한 것입니다.

 

 

5. Controller 코드

@RestController
public class SampleController {
		
	@GetMapping(path="/ajax")
	public Map<String, Object> ajax(@RequestParam(name="type") String type){
		Map<String, Object> map = new HashMap<>();
		String result = type + " Ajax 요청 성공!";
		map.put("result", result);
		return map;
	}

}

파라미터로 받은 type 값 뒤에 " Ajax 요청 성공!"을 더해서 리턴합니다.

 

 

6. 전체 코드

sample.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Ajax</title>
<script src="<%=request.getContextPath() %>/js/jquery-3.3.1.js"></script>
</head>
<body>

<h3>XMLHttpRequest/jQuery Ajax</h3>
&nbsp;<button id="btnXMLHttpRequest">XMLHttpRequest Ajax</button>&nbsp;
<button id="btnjQuery">jQuery Ajax</button>
<div id="divAjax" style="width: 250px; height: 50px; margin-top: 5px; border: 1px solid black"></div>

<script>
/* XMLHttpRequest를 이용한 Ajax */
var btn = document.querySelector("#btnXMLHttpRequest");
btn.addEventListener('click', function(){
	
	var oReq = new XMLHttpRequest();
	oReq.addEventListener("load", function () {
		var data = JSON.parse(oReq.responseText);
		var div = document.querySelector("#divAjax");
		div.innerHTML = data.result;			

	});
	oReq.open("GET", "<%=request.getContextPath()%>/ajax?type=XMLHttpRequest");
	oReq.send();
	
});

/* jQuery를 이용한 Ajax */
$("#btnjQuery").click(function(){

	$.ajax({
		url : "<%=request.getContextPath()%>/ajax",
		data : "type=jQuery",
		type : "GET",
		success : function(data){
			$("#divAjax").html(data.result);
		}
	});
	
});
</script>

</body>
</html>

 

SampleController.java

package sample.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {
		
	@GetMapping(path="/ajax")
	public Map<String, Object> ajax(@RequestParam(name="type") String type){
		Map<String, Object> map = new HashMap<>();
		String result = type + " Ajax 요청 성공!";
		map.put("result", result);
		return map;
	}

}

1. properties 파일을 사용하는 이유

실제 서비스 개발을 할 때는 개발용 DB, 테스트용 DB, 서비스용 DB 등이 따로 나눠져있어서 Java 코드는 수정하지 않고,
application.properties와 같은 파일만 바꿔서 사용하는 방식으로 각 환경에 필요한 패키지를 빌드한다.
또, Github 등에 코드를 공개할 때 비밀번호처럼 공개되면 안되는 정보들을 properties 파일에 정리한 후
.gitignore를 통해 제외하면 안전하게 관리할 수 있다.

 

 

2. application.properties 파일 생성 (src/main/resources/application.properties)

spring.datasource.username=username
spring.datasource.password=password

 

 

3. SampleConfig.java 생성

@Configuration
@PropertySource("classpath:application.properties")
public class SampleConfig { 
    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;
}

@PropertySource에 경로를 입력해주면 @Value 어노테이션을 이용해서 해당 properties 파일에 있는 값을 사용할 수 있다.

+ Recent posts