728x90
728x90

자바스크립트의 일급 객체인 함수 정의하는 방법, 인수, 재귀 함수, 클로저, 고차함수, ES6의 새로운 기능 등에 대해 배웁니다.

 

 

 

1. 함수 정의하기


정의하는 방법

 

1) 함수 선언문으로 정의

function square(x) { return x*x; }

 

2) 함수 리터럴로 정의

var square = function(x) { return x*x; }

 

3) Function 생성자로 정의

var square = new Function("x", "return x*x");

 

4) 화살표 함수 표현식으로 정의 (ES6)

var square = x => x*x;

 

JS 엔진은 호출문 뒤에 함수 선언문이 있어도 프로그램이나 함수의 첫번째 줄로 끌어올려 호출할 수 있으나 함수 리터럴, Function 생성자, 화살표 함수 표현식으로 정의한 함수는 변수에 함수의 참조를 할당해야 사용할 수 있습니다. (=호출 코드보다 앞에 있어야 됩니다.)

 

 

중첩 함수

 

특정 함수 내부에 선언된 함수로 Nested Function이라고 합니다. 지역함수 또는 내부함수라고도 합니다. 외부 함수의 최상위 레벨에만 중첩 함수를 작성할 수 있습니다. 즉 함수 내 if문과 while 문 등의 문장 블록 안에는 중첩함수를 작성할 수 없습니다.

 

// 제곱합에 대한 제곱근 구하기

function norm(x) {
	var sum2 = sumSquare();
  return Math.sqrt(sum2); //제곱근 반환 함수
  
  function sumSquare(){
  	sum=0;
    
    for(var i=0; i<x.length; i++) sum+= x[i]*x[i];
    	// console.log(sum); //88
    return sum; 
  }
}
var a = [2,1,3,5,7];
var n = norm(a);
console.log(n); // 9.380...

 

중첩 함수의 참조는 중첩함수를 둘러싼 외부 함수의 지역 변수에 저장되므로 외부 함수의 바깥에서는 읽고 쓸 수 없습니다.

또한 자신을 둘러싼 외부 함수의 인수와 지역 변수에 접근할 수 있다는 중요한 성질이 있습니다. 예제의 중첩함수 sumSquare는 변수 x를 사용합니다. 이 변수 x는 외부 함수인 norm 의 인수입니다. 

외부 함수의 변수 유효 범위가 그 함수의 중첩함수에까지 미친다는 규칙은 클로저의 핵심 구성 요소가 됩니다.

 

 

 

 

2. 함수 호출하기


호출/실행하는 방법

 

1) 함수 호출 : 함수의 참조가 저장된 변수 뒤 그룹 연산자()를 붙여서 호출

var s = square(5);

 

2) 메서드 호출 : 객체의 프로퍼티에 저장된 값이 함수 타입일 때 그 프로퍼티를 메서드라고 부릅니다. 메서드를 호출할 때 그룹 연산자인 ()를 붙여서 호출합니다. (1)과 본질적으로 같습니다.

obj.m = function(){...};
obj.m();

 

3) 생성자 호출 : 함수나 메서드를 호출할 때 함수의 참조를 저장한 변수 앞에 new 키워드를 추가하면 함수가 생성자로 동작합니다.

var obj = new Object();

 

4) 함수의 call, apply 메서드를 사용한 간접 호출

 

 

 

즉시 실행 함수

 

익명함수를 실행할 때에는 익명 함수의 참조를 변수에 할당한 뒤에 그룹 연산자()를 붙여 실행합니다. 일반 함수를 익명함수를 정의하고 곧바로 실행하는 즉시실행함수로 바꾸겠습니다. 

 

var f = function(){...};
f();
// 일반 함수
// 함수 정의식을 함수 값으로 변환

 

첫 번째, 두 번째 모두 사용 가능합니다. 즉시실행함수 구문에서 함수 정의식을 그룹 연산자()로 묶습니다. 그러면 괄호 안 함수 정의식이 평가되어 함수 값(함수 객체의 참조 값)으로 바뀝니다.

 

(function() {...})();
(function() {...}());
+function() {...}()
// 이렇게 사용해도 함수 정의식을 함수 값으로 만들 수 있다.

 

즉시실행함수도 인수를 넘길 수 있습니다.

 

(function(a,b) {...})(1,2); //a에 1, b에 2 대입

 

즉시실행함수에도 이름을 붙일 수 있지만 그 이름은 함수 내부에서만 유효합니다.

(function fact(n){
	if(n<=1) return 1;
    return n*fact(n-1);
})(5); //120

 

변수에 즉시실행함수 저장 : 함수 실행결과를 변수에 할당할 수 있으며 표현식 안에서 사용할 수 있습니다.

 

var x = (function() { ... } )();

 

즉시실행함수는 전역유효범위를 오염시키지 않는 이름 공간을 생성할 때 사용합니다.

 

 

 

3. 함수의 인수


인수 생략

함수 호출 시 인수 생략이 가능하며, 함수 정의식에 작성된 인자 개수보다 더 많은 개수의 인수를 넘겨서 함수를 실행할 수 있습니다. 

함수 정의식에 작성된 인자 개수보다 인수를 적게 전달해서 함수를 실행하면 인수에서 생략한 인자는 undefined가 됩니다.

 

function f(x,y){
	console.log("x: " + x + ", y: "  + y);
}
f(2); // x:2, y:undefined

 

이를 이용하면 함수 호출 시 인수를 생략할 수 있는 함수를 정의할 수 있습니다. 함수 정의식에서 인수를 생략했을 때 사용할 초기값을 설정해줍니다. 

 

function multiply(a, b){
	b = b || 1; //초기값 1
	return a*b;
}
multiply(2,3); //6
multiply(2); //1

 

논리합연산자 || 는 왼쪽 피연산자가 true면 왼쪽 피연산자를 반환하고, false면 오른쪽 피연산자를 반환합니다. 인자 b에 값을 넘기면 true가 되어 인자 b에 들어온 값을 사용하고 값이 없으면 undefined므로 false로 평가되어 1이 됩니다.

 

 

가변 길이 인수 목록 (Arguments 객체)

모든 함수에서 사용할 수 있는 지역변수로는 arguments 변수가 있습니다. arguments 변수의 값은 Arguments 객체입니다. 함수에 인수를 n개 넘겨서 호출하면 인수 값이 arguments에 저장됩니다.

 

arguments[0] : 첫 번째 인수 값
arguments[1] : 두 번째 인수 값
...
arguments[n-1] : n번째 인수 값

 

Arguments 객체는 프로퍼티로 length와 callee를 갖고 있으며 각각 다음과 같은 값이 담겨 있습니다. Arguments 객체는 배열이 아니고 유사배열객체입니다. (추가)

 

arguments.length : 인수 개수
arguments.callee : 현재 실행되고 있는 함수의 참조

 

arguments[i] 값을 바꾸면 i+1번째 인자가 있을 때 값이 함께 바뀝니다. arguments[1] 값을 바꾸면 함수의 인자 y 값이 같이 바뀝니다. 일반 배열은 이런 성질이 없습니다. arguments 변수를 활용하면 인수 개수가 일정하지 않은 가변 인수 함수를 정의할 수 있습니다.

 

function f(x, y) {
	arguments[1] = 3;
	console.log("x=" + x + ", y = " + y);
}
f(1, 2); // x = 1, y = 3
function myConcat(seperator) {
	var s ="";
	for(var i=1; i<arguments.length; i++){
	s += arguments[i];
	if(i<arguments.length-1) s+= seperator;
	}
	return s;
}
console.log(myConcat("/", "apple", "orange", "peach")); //apple/orange/peach

 

위 예제는 문자열을 연결하는 함수입니다.
유사배열객체인 arguments[]를 배열 객체로 변환하려면 배열메서드인 slice, call을 이용합니다.

 

var params = [].slice.call(argumetns);

 

 

 

 

4. 재귀함수


재귀 호출 (recursive call) : 함수가 자기자신을 호출하는 것

재귀함수는 재귀호출을 수행하는 함수.

 

// n의 팩토리얼을 구하는 함수

function fact(n){
	if(n<=1) return 1;
	return n*fact(n-1);
}
fact(5); //120

 

함수 fact를 리터럴로 정의하려면 함수 리터럴 표현식에 함수 이름을 적으면 되며, 이 함수 이름은 함수 안에서만 유효합니다.

 

var fact = function(n){
	if(n<=1) return 1;
	return n*f(n-1);
}

 

argument.callee를 사용하면 익명 함수도 재귀 호출을 할 수 있습니다. argument.callee 가 지금 실행중인 함수를 가리키기 때문입니다.

 

var fact = function(n){
	if(n<=1) return 1;
	return n*arguments.callee(n-1);
}

 

 

 

재귀 함수 정의의 규칙

 

1. 재귀 호출은 반드시 중간에 멈춰야 한다.

함수가 자신을 호출하면 무한 연쇄 호출로 이어지므로 프로그램이 멈추지 않을 수 있어 중간에 멈출 수 있게 해야 합니다. 

2. 재귀 호출로 간단한 문제 해결이 가능할 때만 사용한다.

재귀 함수는 재귀 호출이 멈출 때까지 반복해서 자기자신을 호출합니다. 호출된 각각의 재귀함수는 메모리의 다른 영역을 사용합니다. 따라서 호출횟수만큼 메모리 소비량이 늘어납니다.

반복문을 재귀함수로 바꿔 표현할 수도 있지만, 재귀함수보다 while문이나 for문이 이해도 쉽고 메모리 공간도 적게 차지합니다. 따라서 꼭 필요할 때만 사용합니다.

 

 

 

재귀 함수 예시

 

퀵 정렬은 찰스 앤터니 리처드 호어가 발표한 정렬로 어떤 배열을 오름차순으로 정렬하는 알고리즘입니다. 퀵 정렬은 배열을 둘로 나눈 후 나눈 부분을 대상으로 퀵 정렬을 재귀적으로 반복합니다. 퀵 정렬 알고리즘은 다음을 따릅니다.

 

1. p값 이상인 요소의 개수와 p값 이하인 요소의 개수가 거의 같게끔 p값을 설정한다.

2. 배열 앞부분에는 p값 이상인 요소를 옮기고, 뒷부분에는 p값 이하인 요소를 옮긴다.

3. 배열 앞부분의 길이가 2 이상이면 그 부분을 대상으로 퀵 정렬을 한다.

4. 배열 뒷부분의 길이가 2 이상이면 그 부분을 대상으로 퀵 정렬을 한다.

 

// x : 정렬할 배열
// first :  정렬할 첫 번째 요소의 위치
// last : 정렬할 마지막 요소의 위치

function quicksort(x, first, last) {
  var p = x[Math.floor((first + last) / 2)];
  
  for (var i = first, j = last; ; i++, j--) {
    while(x[i]<p) i++; // 왼쪽부터 차례로  p 이상의 요소를 검색
    while(p<x[j]) j--; // 오른쪽부터 차례로 p 이하의 요소를 검색
    
    if(i>=j) break; // i와 j가 교차하면 다음으로 이동
    var w = x[i]; x[i] = x[j]; x[j] = w; // 발견하면 x[i]와 x[j]를 교환한다
    
  }
  if(first<i-1) quicksort(x, first, i-1); // 왼쪽에 두 개 이상 남았으면 왼쪽을 다시 정렬
  if(j+1<last) quicksort(x, j+1, last); // 오른쪽에 두 개 이상 남았으면 오른쪽을 다시 정렬 

}

var a = [7, 2, 5, 1, 8, 9, 3];
quicksort(a, 0, a.legnth-1);
console.log(a); // [1,2,3,5,7,8,9]

 

** 코드 오류 찾아보기

 

 

 

 

5. 프로그램의 평가와 실행 과정


실행 가능한 코드

JS 엔진은 실행 가능한 코드 (Executable Code)  를 만나면 그 코드를 평가(Evaluation)해 실행 문맥으로 만듭니다. 실행 가능한 코드의 유형은 전역 코드, 함수 코드, eval 코드 (eval 함수)가 있습니다. 

전역 코드는 전역 객체 Window 아래에 정의된 함수, 함수 코드는 함수, eval 코드는 eval 함수입니다.

JS 엔진이 실행 가능한 코드의 유형을 분류하는 이유는 실행 문맥을 초기화하는 환경과 과정이 다르기 때문이며, 특히 eval 코드는 Lexical Environment 이 아니라 별도 동적 환경에서 실행됩니다. 

 

실행 문맥의 구성

실행 문맥 (Execution Context)은 실행가능한 코드가 실제로 실행되고 관리되는 영역으로 실행에 필요한 모든 정보를 컴포넌트 여러 개가 나누어 관리하도록 만들어져 있습니다. 가장 중요한 컴포넌트는 아래 3가지입니다.

  • LexicalEnvironment (렉시컬 환경) 컴포넌트

  • VariableEnvironment(변수 환경) 컴포넌트

  • This Binding 컴포넌트

 

// 객체 표현을 빌린 의사 코드 (실행 불가)

// 실행 문맥
ExecutionContext = {
	// 렉시컬 환경 컴포넌트
	LexicalEnvironment: {},
	// 변수 환경 컴포넌트
	VariableEnvironment: {},
	// 디스 바인딩 컴포넌트
	ThisBinding: null,
}

 

렉시컬 환경 컴포넌트 변수 환경 컴포넌트는 렉시컬 환경 타입의 컴포넌트입니다. 둘은 타입이 같고 with문을 쓸 때 외에는 내부 값이 같아 똑같이 취급하며, 설명도 통일합니다. 디스 바인딩 컴포넌트함수를 호출한 객체의 참조가 저장되는 곳입니다. 이것이 가리키는 값이 곧 해당 실행 문맥의 this가 됩니다.

 

 

LexicalEnvironment (렉시컬 환경) 컴포넌트의 구성

* lexical : 어휘

실행 문맥의 구성 요소인 렉시컬환경 컴포넌트는 JS 엔진이 JS 코드를 실행하기 위해 자원을 모아둔 곳으로
함수나 블록의 유효 범위 안에 있는 식별자와 그 결과값이 저장되는 곳

JS 엔진은 해당 JS 코드의 유효 범위 안에 있는 식별자와 그 식별자가 가리키는 값을 키/값의 쌍으로 바인드(묶다)해서 렉시컬 환경 컴포넌트에 기록합니다.

 

// JS의 객체 표현을 빌린 의사 코드

LexicalEnvironment: {
	// 환경 레코드
    EnvironmentRecord: {},
	// 외부 렉시컬 환경 참조
	OuterLexicalEnvironment Reference: {}
}

 

렉시컬 환경 컴포넌트는 환경 레코드외부 렉시컬 환경 참조 컴포넌트로 구성되어 있습니다.

 

환경 레코드 : 유효 범위 안에 포함된 식별자를 기록하고 실행하는 영역
ECMAScript 3의 변수 객체(Variable Object)와 비슷한 역할입니다.
JS 엔진은 유효 범위 안의 식별자와 결과값을 바인드해서 환경 레코드에 기록합니다.

외부 렉시컬 환경 참조 : JS 는 함수 안에 함수를 중첩해서 정의할 수 있는 언어입니다. 따라서 JS 엔진은 유효 범위 너머의 유효 범위도 검색할 수 있어야 합니다. 외부 렉시컬 환경 참조 Outer Lexical Environment Reference에는 함수를 둘러싸고 있는 코드가 속한 렉시컬 환경 컴포넌트의 참조가 저장됩니다.
중첩 함수 내에서 바깥 코드에 정의된 변수를 읽거나 써야할 때, JS 엔진은 외부 렉시컬 환경 참조를 따라 한 단계씩 렉시컬 환경을 거슬러 올라가 그 변수를 검색합니다.

 

 

 

환경 레코드의 구성

렉시컬 환경 컴포넌트의 구성 요소인 환경 레코드(Environment Record)렉시컬 환경 안의 식별자와 이 식별자가 가리키는 값의 묶음실제 저장되는 영역입니다.

이 환경 레코드는 선언적 환경 레코드객체 환경 레코드로 구성되어 있으며 저장하는 값의 유형에 따라 쓰임새가 달라집니다.

// JS의 객체 표현을 빌린 의사 코드로 환경 레코드 표현

EnvironmentRecord: {
	// 선언적 환경 레코드
    DeclarativeEnvironmentRecord: {},
	// 객체 환경 레코드
	ObjectEnvironmentRecord: {}
}

 

선언적 환경 레코드

Declarative Environment Record는 실제로 함수와 변수, catch 문의 식별자와 실행 결과가 저장되는 영역입니다.

 

객체 환경 레코드

선언적 환경 레코드가 식별자와 실행결과를 키와 값의 쌍으로 관리하는 반면,
객체 환경 레코드 (object environment records)는 실행 문맥 외부에 별도로 저장된 객체의 참조에서 데이터를 읽거나 씁니다.

with 문의 렉시컬 환경이나 전역 객체처럼 별도의 객체에 저장된 데이터는 그 객체가 가진 키와 값의 쌍을 복사해 오는 것이 아니라 그 객체 전체의 참조를 가져와서 객체 환경 레코드의 bindObject라는 프로퍼티에 바인드하도록 만들어져 있습니다.

 

 

전역 환경과 전역 객체의 생성

JS 인터프리터는 시작하자마자 렉시컬 환경 타입의 전 환경을 생성합니다. 웹 브라우저에 내장된 JS 인터프리터는 새 웹 페이지를 읽어들인 후 전역 환경을 생성합니다.

그리고 전역 객체를 생성한 후 전역 환경의 객체 환경 레코드에 전역 객체의 참조를 대입합니다. 전역 객체에는 undefined, NaN, INfinity와 같은 프로퍼티가 있으며 최상위 레벨 (함수 바깥에 있는 코드)의 this는 전역 객체를 가리킵니다.

 

this === window //true

 

이 코드의 상태를 의사 코드로 표현하면 다음과 같습니다.

 

// 전역 환경
GlobalEnvironment = {
	ObjectEnvironmentRecord:{
		bindObject: window
	},
    OuterLexicalEnvironmentReference: null
}

// 전역 실행 문맥
ExecutionContext = {
	LexicalEnvironment: GlobalEnvironment,
	ThisBinding: window,
}

 

웹브라우저의 JS 실행 환경에서는 Window 객체가 전역 객체이므로 객체 환경 레코드의 bindObject 프로퍼티에는 전역 객체 Window의 참조가 할당됩니다. 이로 인해 전역 환경의 변수와 함수를 Window 안에서 검색하게 됩니다. 또한 전역 환경의 외부에는 다른 렉시컬 환경이 없으므로 외부 렉시컬 환경 참조에는 null을 할당합니다. 

전역 실행 문맥의 디스 바인딩 컴포넌트에도 Window의 참조가 할당되어 전역 실행 문맥의 this가 Window를 가리키게 되고, 전역 실행 문맥의 프로퍼티를 디스 바인딩 컴포넌트 안에서 검색하게 됩니다. 

Window 객체는 Window 객체의 프로퍼티인 window로 참조할 수 있습니다. Window 객체에는 일반 전역 객체의 프로퍼티와 클라이언트 측 JS에서만 사용할 수 있는 다양한 프로퍼티가 정의되어 있습니다. (Window객체는 13장으로)

 

 

프로그램의 평가와 전역 변수

전역환경과 전역 객체를 생성한 후에는  JS 프로그램을 읽어들입니다. 다 읽어들인 후 프로그램을 평가하며, 최상위 레벨에 var 문으로 작성한 전역 변수는 전역 환경의 환경 레코드(객체 환경 레코드)의 프로퍼티로 추가됩니다.

 

// 전역 환경
GlobalEnvironment = {
	// 전역 환경의 환경 레코드인 객체 환경 레코드에 Window의 참조가 설정되어 있음
	ObjectEnvironmentRecord:{
		bindObject: window
	},
    OuterLexicalEnvironmentReference: null
}

 

 

JS 엔진은 전역 코드를 평가할 때 최상위 레벨에 var 문으로 작성한 전역 변수를 전역 환경의 환경 레코드(객체 환경 레코드)에 프로퍼티로 기록합니다. 그 프로퍼티 이름은 식별자 이름이 되고 프로퍼티 값은 undefined가 됩니다.

함수의 경우에는 최상위 레벨에 작성된 함수 선언문을 함수 객체로 생성해서 전역 환경의 환경 레코드(객체 환경 레코드)에 프로퍼티로 기록합니다.

 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

닷홈을 이용하였는데 admin 관리자 계정에 비밀번호가 공지가 안되어 있어서 재설정했습니다.

 

 

 

 

phpmyadmin(주소 : 도메인/myadmin)에 가면 워드프레스 admin 초기 비밀번호를 조회 가능하지만 워드프레스의 방식으로 암호화가 되어 있어서 그대로 로그인 창에 복붙해도 로그인이 되지 않습니다. 눈으로 봐도 영어와 숫자, 기호 등이 섞여 복잡합니다. 따라서 아래 방법에 따라 재설정해줍니다.

 

 

 

 

admin계정의 비번을 admin으로 설정하는 방법입니다. phpMyAdmin에 접속하여 wp_users컬럼 user_pass value에 아래 값을 붙여넣으면 됩니다. 아래 값은 영문 admin을 의미합니다. (출처)  

 

21232f297a57a5a743894a0e4a801fc3

 

 

 

 

차후 비밀번호를 수정하려면, 관리자 페이지에서 UI를 보며 수정 가능합니다.

 

 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

업무일지의 개인적인 가이드. 에버노트 같은 데에 메모하면서 일한 적은 있으나 용량 때문에 길게 보관하지 않았다. 결과물 빼고 너무 다 지워버렸더니 나중에 기간 등이 궁금해도 찾아볼 수가 없어 이제 좀 남기기로 했다. 보고도 할 겸, 업무 효율과 자기 발전도 이룰 겸 앞으로 적어나갈 업무일지의 가이드를 정리해보았다.

 

 

업무일지는 이렇게 작성


진행할 업무목표, 실천사항 (종결/미종결 구분)을 쓰는 것.
세분화하려면 오전/오후나 시간별로 정리한다.

크게 분류하면 하루 업무내용, 업무진척상황, 활동 성과와 관련된 내용이며
업무 요약은 핵심 내용을 담아 간결하게 작성한다.
기간이나 업무별로 계획을 짜며 진행사항도 적는다.

단기든 장기든 목표설정을 해 둔다.
실적과 목표는 수치화하여 객관적으로 쓴다.
회의가 있었다면 지시사항도 적어보자.

 

 

작성하면서 체크할 것


고민을 하면서 다양한 방식으로 문제에 접근했는가?
현황/문제점/원인 등 이슈 분석은 충분했는가?
실천 가능성 없는 대안은 아닌가?
향후 계획이 확실한가?
내 보고서를 읽고 무엇을 해야할 지 명확하게 나타나 있는가?

 

 

 

업무일지 예시


출처 : 개기획자 https://bizdevelop.tistory.com/94

https://bizdevelop.tistory.com/94

 

 

 

 

 

활용해 볼 만한 툴


1. Google Drive - 구글 드라이브의 설문 양식 기능을 활용한다. 양식을 만들어 둔 후 폼에 기록하면 구글드라이브에 엑셀 형식대로 순서대로 정리된다.

2. MS OneNote - 년, 월, 일로 카테고리를 만들어 업무를 입력할 수 있다. 페이지 개념이라 파일 첨부, 음성녹음도 가능한 등 자유로운 형태로 많은 양의 작성도 가능

3. Evernote - 원노트와 유사하다. 처음에 소개받고 사막의 오아시스 같이 반가워서 강의메모, 업무 기록, 회의 기록 등에 잘 썼었는데 점점 내게는 작성툴이 불편하게 다가왔다. PC, 스마트폰 등 연동이 된다. 브라우저에서 보던 화면/기사 등을 플러그인으로 바로 캡쳐할 수 있는 점은 편하다. 다른 메모 툴로는 Notion도 있음

4. 앱스토어 등에서 GTD(Getting Things Done) 키워드로 검색

5. Trello 

6. 분더리스트

 

 

 

 

GTD(Getting Things Done) 란 무엇인가

 


https://m.blog.naver.com/hasajon/220648576335

 

효율적으로 일 잘하는 방법: Getting Things Done (GTD) 도표 설명

효율적으로 일 잘하는 방법: Getting Things Done (GTD) 도표 설명 GTD의 핵심원리는 주어진 일들...

blog.naver.com

https://brunch.co.kr/@soho-works/135

 

GTD 할 일 정리의 기술

제14화 《쏟아지는 일 완벽하게 해내는 법》 데이비드 앨런 | 적게 일하고 많이 버는 고수가 되기 위한 ‘생산성 높이기 프로젝트’. 일과 삶, 그리고 당신의 하루에 필요한 생산성을 연구합니��

brunch.co.kr

https://evernote.com/blog/ko/getting-things-done/

 

GTD(Getting Things Done) 시작하기

생산성 전문가 Tiago Forte와 Simplify Days가 손을 잡고 GTD(Getting Things Done)를 시작하는 데 필요한 조언과 Evernote 템플릿을 나누어 드립니다.

evernote.com

 

 

 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

일정 단위로 값을 고정된 것이 아닌 변화에 따라 정해둔 비율로 변동이 가능하게 해 본다. 

 

가변 그리드 (Fluid Grid) : 일정 단위로 값을 고정된 것이 아닌 변화에 따라 정해둔 비율로 변동이 가능하게끔 제작하는 것. 공식은 수학시간에 퍼센트를 만드는 것과 같은가본데 그런수학과 거리가 멀어서 식을 모르기에 검색했다.

 

( 반응형 너비 / 전체 너비 ) * 100

 

마진, 패딩, 폰트 역시 가변 그리드 표기법 (%)을 이용해 나타낼 수 있다! max-width 속성값을 100%로 설정할 경우 요소의 기본 크기 이상으로는 늘어나지 않는다.

 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

제어구문은 프로그램의 처리흐름을 제어하는 문장으로 알고리즘에 담긴 논리를 표현하고 본격적으로 프로그램을 만들 수 있습니다. 

 

 

 

 

1. 제어구문


순차적 실행

일반적으로 문장은 위에서부터 아래방향으로 순서대로 실행됩니다. 순차적 실행 흐름을 변화시키는 문장을 제어 구문이라고 하며, JS에서는 아래와 같은 제어 구문이 있습니다. 

 

분류 제어 구문 설명
조건문 if/else, switch, try/catch/finally 조건에 따라 처리를 분기
반복문 while, do/while, for, for/in, for/of 조건 만족 시 처리 반복 실행
점프문 break, continue, return, throw 프로그램의 다른 위치로 이동

 

 

 

2. 조건문


조건문은 조건식의 값에 따라 실행 흐름을 분기합니다.

 

if/else 문

true면 문장 1, false면 문장 2 를 실행합니다. 조건식의 소괄호는 꼭 입력해야 합니다. if 문 안에 if 문을 중첩해서 쓸 수 있고, if else if {} else if {} .... else {} 와 같이도 쓸 수 있습니다.

사용법 1 if (조건식) 문장
사용법 2 if (조건식) 문장 1 else { 문장 2 }

 

switch 문

if/else 문은 표현식의 값에 따라 실행을 분기할 때 사용합니다. 분기점 여러개를 구현하고자 할 때 switch 문을 사용하면 더 간결해집니다. 대괄호 안에 default : 실행문 + 1 (문장) 을 넣으면 어느 case 에도 속하지 않을 때 실행할 문장입니다. 

 

switch (표현식) { 
	case 표현식 1 : 실행문 1 ( 문장 ) 
	case 표현식 2 : 실행문 2 ( 문장 ) ... 
	case 표현식 n : 실행문 n ( 문장 ) 
	default: 실행문n + 1 (문장)
}

 

 

 

 

 

3. 반복문


반복문은 일정한 처리를 한 후 원래 위치로 돌아가 같은 처리를 반복합니다. for/of 문은 8단원에서 더욱 자세히 설명합니다.

 

while 문

조건만 맞으면 일정한 처리를 계속 반복해 실행합니다. 가장 먼저 조건식을 평가한 후 결과가 false면 문장을 나와 다음 처리를 시작하며 true이면 문장을 실행 후 다시 시작 부분으로 돌아가서 평가하기를 반복합니다. 문장 내에서 break 를 실행하면 문장에서 빠져나오며, continue를 실행하면 시작 부분으로 돌아갑니다.

 

while (조건식) 문장

 

예제 : 순차 검색 (배열 a에서 x값과 같은 요소를 찾아내기 = 선형검색)

function linearSearch(x, a) {
  var i = 0;
  var n = a.length;

  while (i < n && x > a[i]) i++;

  if (x == a[i]) return i;

  return null; // x와 같은 값이 없으면
}

var a = [2, 4, 7, 12, 15, 21, 34, 35, 46, 57, 70, 82, 86, 92, 99];
console.log(linearSearch(35, a));  // 7

 

선형검색 vs 이진검색

이진검색 : 정렬된 배열에서 가운데 요소의 값을 기준으로 반을 나눈 후 둘 중 어디에 검색할 값이 저장되어있는지 예측하는 것을 재귀적으로 반복해 나가는 방법. 

 

function binarySearch(x, a) {
	var n = a.length;
	var left = 0, right = n-1;
	while(left<right) {
		var middle = Math.floor((left+right)/2);
		if(x<=a[middle]){
			right = middle;
		}else{
		left = middle + 1;
		}
	}
	if(x==a[right]) return right;
	return null;
}

var a = [2, 4, 7, 12, 15, 21, 34, 35, 46, 57, 70, 82, 86, 92, 99];
console.log(binarySearch(35, a));  // 7

 

 

 

do/while 문

문장 먼저 실행한 후, 반복해서 실행할 지를 마지막 부분에서 판단합니다. break문과 continue 문을 사용할 수 있습니다.

 

do 문장 while (조건식);

 

 

 

for문

소괄호 안에서 반복 조건의 초기화, 반복문의 조건식, 반복조건 갱신 작업을 한번에 표기합니다. for문 안에 for문을 작성하여 중첩 반복문을 만들 수도 있습니다.

 

for (초기화 식; 조건식; 반복식) 문장
// 피타고라스의 수 구하기
var n = 20;
for(var a=1; a<=n; a++){
	for(var b=1; b<=n; b++){
		for(var c=1; c<=n; c++){
			if(a*a + b*b == c*c) {
				console.log(a + "^2+" + b + "^2=" + c + "^2");
			}
		}
	}
}

 

 

 

for/in 문

객체 안의 프로퍼티를 순회합니다. 실행되면 먼저 객체 표현식을 평가하고, null 또는 undefined로 평가되면 for/in문을 빠져나와 다음 작업으로 이동합니다. 객체표현식이 객체로 평가되면 객체의 프로퍼티 이름이 변수에 할당되고 각각의 프로퍼티에 대해 문장이 한 번씩 실행됩니다.

 

for (변수 in 객체표현식) 문장
var obj = {a:1, b:2, c:3};
for(var p in obj) {
	console.log("p=" + p);
}
// "p=a" "p=b" "p=c"

 

각 프로퍼티의 이름을 "a", "b", "c"라는 문자열로 바꾸어 변수 p에 대입하는 문장이 실행됩니다.  프로퍼티 이름이 아니라 프로퍼티 값을 가지고 오려면 괄호 연산자를 사용합니다. 반복문 내에서 문장을 여러개 실행하려면 여러 문장을 블록으로 묶어 블록문으로 만듭니다. for/in문 내에서도 break/continue 문을 쓸 수 있습니다. 

 

var obj = {a:1, b:2, c:3};
for(var p in obj) {
	console.log("obj." + p + "=" + obj[p]);
}
// "obj.a=1" "obj.b=2" "obj.c=3"

 

 

 

 

4. 점프문


프로그램의 다른 위치로 이동합니다. break, continue, return, throw 문이 있습니다. 문장에 라벨을 붙이면 break문이나 continue문 실행 후 점프할 수 있는 위치가 됩니다. 

 

라벨문

JS에서는 모든 문장에 라벨을 붙일 수 있습니다. 라벨 이름에는 모든 식별자를 사용할 수 있습니다. JS에서는 라벨로 점프할 수 있는 문장은 break, continue문 뿐입니다. break문은 switch문과 반복문 안에서만 사용할 수 있고 continue문은 반복문 안에서만 사용할 수 있습니다. --> 라벨을 붙여 사용할 수 있는 문장은 switch문과 반복문

 

라벨이름 : 문장
loop: while(true){
	if(confirm("종료할건가?")) break loop;
}

 

 

break 문

break문은 switch문과 반복문 안에서만 사용할 수 있습니다. 실행하면 가장 안쪽의 반복문이나 switch문에서 빠져나옵니다. 점프할 라벨을 지정할 수도 있습니다. 라벨을 지정한 break문을 실행하면 라벨이 붙은 문장 끝으로 점프하며, break문에서 지정한 라벨이 없으면 문법 오류가 발생합니다. 라벨을 지정한 breka문은 switch, 반복문에서 사용할 수 있으며 라벨을 지정한 모든 문장에서 사용할 수 있습니다.

 

break 라벨 이름;
// 두 배열에서 같은 값을 가진 요소를 발견하면 전체 반복문에서 빠져나오는 코드

var a = [2, 4, 6, 8, 10],  b = [1, 3, 5, 6, 9, 11];

loop: for (var i = 0; i < a.length; i++) {
  for (var j = 0; j < b.length; j++) {
    if (a[i] == b[j]) break loop; // 라벨을 지정하여 전체 반복문을 빠져 나옴
  }
}

console.log("a[" + i + "] = b[" + j + "]"); //"a[2] = b[3]"

 

라벨을 지정한 break문은 주로 중첩반복문의 안쪽 반복문에서 전체 반복문을 빠져나올 때 사용합니다.

또한 break문과 라벨 이름 사이에 줄 바꿈 문자를 넣지 않도록 유의합니다. 들어갔을 시 아래와 같은 오류가 납니다. (엔진이 자동으로 세미콜론을 추가하여 라벨을 지정하지 않은 break문으로 해석)

 

"<a class='gotoLine' href='#31:5'>31:5</a> Uncaught ReferenceError: loop is not defined"

 

 

 

continue 문

continue문을 실행하면 반복문 실행을 멈추고 반복을 새로 시작합니다. continue문에도 점프할 라벨을 지정할 수 있으며, continue 문은 라벨 지정 여부와 관계없이 반복문 안에서만 사용할 수 있는 것이 break문과 차이점입니다. 표와 같이 반복문에 따라 동작이 달라집니다.

 

continue;
continue 라벨 이름;

 

while 반복문의 처음으로 되돌아가서 조건식을 재평가. true면 처음부터 반복문 실행
do/while 중간을 건너뛰고 반복문의 마지막 조건식을 평가. true면 처음부터 반복문 실행
for 반복식 실행 후 조건식 평가. true면 반복문 이어서 실행
for/in문 반복문의 처음으로 되돌아가서 지정한 변수에 할당된 프로퍼티의 다음 프로퍼티를 대상으로 작업 시작

 

 

 

 

 

5. 응용예제 - 암호 원판 만들기


원판 암호는 알베르티의 발명품으로 바깥쪽 원판은 고정형, 안쪽 원판은 회전형으로 원판을 활용해서 암호문으로 치환할 수 있습니다. 예제로 암호 생성기 객체를 반환하는 함수 (객체 팩토리) 를 사용해서 만들어보겠습니다. 

 

객체 팩토리 Encryptor 함수

 

function Encryptor(){
	var obj = {}; return obj;
}

 

기본형은 위와 같고, 바깥쪽 원판의 문자 집합을 chars 프로퍼티에 배열로 저장합니다. 알파벳은 for문을 사용해서 배열에 추가합니다.

 

function Encryptor() {
  var obj = {};

  var N_ALPHABET = 26; //알파벳 문자 개수
  var extraCharactors = [" ", ".", "?", "!", "%", "#", "'", "&", "$", "@", ":", "/"]; //특수문자 배열

  obj.chars = []; //알파벳을 담을 배열

  // chars 배열에 알파벳 소문자 추가
  for (var c = "a".charCodeAt(0); c <= "z".charCodeAt(0); c++) {
    obj.chars.push(String.fromCharCode(c));
  }
	
  console.log(obj.chars); 
  // ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
  return obj;

}

Encryptor();

 

charCodeAt : index에 해당하는 문자의 unicode 값을 리턴. index - 0보다 큰 정수
fromCharCode :  UTF-16 코드 유닛의 시퀀스로부터 문자열을 생성해 반환

 

chars 배열에 소문자 추가한 것에 이어서 대문자와 숫자, 특수문자를 추가합니다.
nchars 프로퍼티에 문자 개수를 저장합니다. (62개)

 

function Encryptor() {
  var obj = {};

  var N_ALPHABET = 26; //알파벳 문자 개수
  var extraCharactors = [" ", ".", "?", "!", "%", "#", "'", "&", "$", "@", ":", "/"]; //특수문자 배열

  obj.chars = []; //알파벳을 담을 배열

  // chars 배열에 알파벳 소문자 추가
  for (var c = "a".charCodeAt(0); c <= "z".charCodeAt(0); c++) {
    obj.chars.push(String.fromCharCode(c));
  }

  // chars 배열에 알파벳 대문자 추가
  for (var c = "A".charCodeAt(0); c <= "Z".charCodeAt(0); c++) {
    obj.chars.push(String.fromCharCode(c));
  }

  // chars 배열에 알파벳 숫자추가
  for (var d = 0; d <= 9; d++) {
    obj.chars.push(d.toString());
  }

  // chars 배열에 알파벳 특수문자 추가
  for (var j = 0; j < extraCharactors; j++) {
    obj.chars.push(extraCharactors[j]);
  }

  // nchars 프로퍼티에 배열 chars에 저장된 문자 개수를 저장
  obj.nchars = obj.chars.length;
  return obj;

} 

 

 

암호화 메서드 추가

암호화할 문자 하나하나를 obj.chars 배열의 요소 번호(0~obj.chars-1 사이의 정수) 가 가리키는 문자로 바꾸는 numberOf(ch)메서드를 추가합니다. 이 메서드는 문자 ch에 있는 obj.chars 요소의 번호를 반환하며 obj.chars 안에 ch가 없다면 null을 반환합니다.

 

  // chars배열에서의 문자 ch의 요소 번호를 구하는 메서드 ( ch를 chars배열에서 찾을 수 없을 때에는 null을 반환함)
  obj.numberOf = function(ch) {
    var code = ch.charCodeAt(0);
    if (code >= "a".charCodeAt(0) && code <= "z".charCodeAt(0)) {
      return code - "a".charCodeAt(0);
    } else if (code >= "A".charCodeAt(0) && code <= "Z".charCodeAt(0)) {
      return N_ALPHABET + code - "A".charCodeAt(0);
    } else if (code >= "0".charCodeAt(0) && code <= "9".charCodeAt(0)) {
      return 2 * N_ALPHABET + code - "0".charCodeAt(0);
    } else {
      for (var k = 0; k < extraCharactors.length; k++) {
        if (ch == extraCharactors[k]) {
          return 2 * N_ALPHABET + 10 + k;
        }
      }
      return null;
    }
  };

 

원판 암호기의 암호문은 키워드가 가리키는 요소의 번호만큼 이동시켜 구합니다. shift메서드는 문자 ch를 정수 n만큼 이동시킨 문자를 반환합니다. 함수 안에서 this가 가리키는 것은 obj입니다.

numberOf 메서드를 사용해서 정수값 num을 구하고 chars 배열 안에서 num이 가리키는 문자를 구합니다. 
정수값을 n만큼 이동시킨 값이 0~obj.nchars-1의 범위 안에서 돌게끔 obj.nchars로 나눈 나머지를 구합니다. 복호화(암호화를 푸는 것)를 하면 n이 음수가 되므로 나머지를 구하기 전에 obj.nchars를 더합니다.

 

  // 문자ch를 n만큼 이동시킨 문자를 반환하는 메서드 ( ch를 chars배열에서 찾을 수 없을 때에는 null을 반환함)
  obj.shift = function(ch, n) {
    var num = this.numberOf(ch);
    
    if (num == null) return ch;
    num = (num + n + this.nchars) % this.nchars;
    
    return this.chars[num];
  };

 

encrypt 메서드는 문자열 text를 키워드 keyword로 encription값이 true면 암호화한 문자열을 반환하고 false면 복호화한 문자열을 반환합니다. 암/복호화 시 이동해야 하는 거리인 nshift를 keyword 문자로 구합니다. keyword의 몇 번째 문자를 가리키고 있는지 알려주는 숫자인 ikey 를 text 안의 문자를 하나 처리할 때마다 1씩 증가시키고, keyword의 길이인 nkey 로 나눈 나머지를 구해 0~nkey-1 안에서 돌게 합니다. encription이 true면 keyword 메서드로 구한 값 자체를 사용하고, false면 값에 -1을 곱해 반대로 돌게 합니다.

 

 

// 원판 암호기로 암호화를 하는 메서드
//   text: 암호화 / 복호화를 할 문자열
//   keyword: 키워드
//   encription: true 면 암호화, false면 복호화
            
obj.encrypt = function(text, keyword, encription) {
    var cipherText = "";
    var nkey = keyword.length;
    
    for (var i = 0, ikey = 0; i < text.length; i++, ikey++) {
      ikey %= nkey;
      var nshift = this.numberOf(keyword[ikey]);
    
    if (!encription) nshift *= -1;
      cipherText += this.shift(text[i], nshift);
    }
    
    return cipherText;
};

 

일반문과 암호문을 입력받는 html 폼을 만들어 JS와 연결합니다. 

 

 

 

완성본

 

<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="UTF-8">
	<title>원판 암호기</title>
	<script>
        window.onload = function() {
            var enscriptor = Enscriptor();
			// 평문을 암호화
            document.getElementById("cipher").onclick = function() {
                var keyword = document.getElementById("keyword").value;
                var plaintext = document.getElementById("plaintext").value;
                var ciphertext = document.getElementById("ciphertext");
                ciphertext.value = enscriptor.encrypt(plaintext,keyword,true);
            };
			// 암호문을 복호화
            document.getElementById("decipher").onclick = function() {
                var keyword = document.getElementById("keyword").value;
                var plaintext = document.getElementById("plaintext");
                var ciphertext = document.getElementById("ciphertext").value;
                plaintext.value = enscriptor.encrypt(ciphertext,keyword,false);
            };
        };
		/*
		 * 함호기 객체를 생성하는 팩토리 함수
		 *   obj.chars: 원판에서 사용할 문자 배열
		 *   obj.nchars: 원판에서 사용하는 문자 배열의 길이 ( chars의 길이 )
		 *   obj.numberOf(ch): 문자 ch가 배열 chars의 몇 번째 요소인지를 반환하는 메서드
		 *   obj.shift(ch,n): 문자 ch를 n만큼 이동시켰을 때 가리키는 chars 배열의 요소
		 *   obj.encrypt(text,keyword,encription): 원판 암호기로 암호화 / 복호화 하는 메서드
		 */
        function Enscriptor() {
            var obj = {};
            var N_ALPHABET = 26;	// 알파벳 문자의 개수
            var extraCharactors = [" ",".","?","!","%","#","'","&","$","@",":","/"];
			// 특수문자 배열
            obj.chars = [];
			// chars 배열에 알파벳 소문자와 대문자를 추가
            for(var c="a".charCodeAt(0); c<="z".charCodeAt(0); c++) {
                obj.chars.push(String.fromCharCode(c));
            }
            for(var c="A".charCodeAt(0); c<="Z".charCodeAt(0); c++) {
                obj.chars.push(String.fromCharCode(c));
            }
			// chars 배열에 숫자를 추가
            for(var d=0; d<=9; d++) {
                obj.chars.push(d.toString());
            }
			// chars 배열에 특수문자를 추가
            for(var j=0; j<extraCharactors.length; j++) {
                obj.chars.push(extraCharactors[j]);
            }
			// chars 배열의 길이
            obj.nchars = obj.chars.length;
			// chars배열에서의 문자 ch의 요소 번호를 구하는 메서드 ( ch를 chars배열에서 찾을 수 없을 때에는 null을 반환함)
            obj.numberOf = function(ch) {
                var code = ch.charCodeAt(0);
                if( code>="a".charCodeAt(0) && code<="z".charCodeAt(0)) {
                    return code - "a".charCodeAt(0);
                } else if(code>="A".charCodeAt(0) && code<="Z".charCodeAt(0)) {
                    return N_ALPHABET + code - "A".charCodeAt(0);
                } else if(code>="0".charCodeAt(0) && code<="9".charCodeAt(0)) {
                    return 2*N_ALPHABET + code - "0".charCodeAt(0);
                } else {
                    for(var k=0; k<extraCharactors.length; k++) {
                        if( ch == extraCharactors[k] ) {
                            return 2*N_ALPHABET + 10 + k;
                        }
                    }
                    return null;
                }
            };
			// 문자ch를 n만큼 이동시킨 문자를 반환하는 메서드 ( ch를 chars배열에서 찾을 수 없을 때에는 null을 반환함)
            obj.shift = function(ch,n) {
                var num = this.numberOf(ch);
                if( num == null ) return ch;
                num = (num + n + this.nchars)%this.nchars;
                return this.chars[num];
            };
			// 원판 암호기로 암호화를 하는 메서드
			//   text: 암호화 / 복호화를 할 문자열
			//   keyword: 키워드
			//   encription: true 면 암호화,false면 복호화
            obj.encrypt = function(text,keyword,encription) {
                var cipherText = "";
                var nkey = keyword.length;
                for(var i=0, ikey=0; i<text.length; i++, ikey++) {
                    ikey %= nkey;
                    var nshift = this.numberOf(keyword[ikey]);
                    if(!encription) nshift *= -1;
                    cipherText += this.shift(text[i],nshift);
                }
                return cipherText;
            };
            return obj;
        }
	</script>
	<style>
		p { font-size:
				smaller; }
		input { height:
				20px; }
		#plaintext,#ciphertext { width:
				500px; }
	</style>
</head>
<body>
    <h2>원판 암호기를 활용한 암호화</h2>
    <p>키워드 : <input type="text" id="keyword"></p>
    <p>평문 : <input type="text" id="plaintext"></p>
    <p>암호문 : <input type="text" id="ciphertext"></p>
    <input type="button" id="cipher" value="암호화">
    <input type="button" id="decipher" value="복호화">
</body>
</html>

 

 

gilbutITbook/006960

Contribute to gilbutITbook/006960 development by creating an account on GitHub.

github.com

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

모달 팝업 배경 부분을 비활성화시키기도 하지만 반대로 활성화해야 할 경우도 있습니다. 그럴 경우 .modal의 pointer-events를 none로 설정합니다.

 

설정

.modal {
  pointer-events: none;
  /* background clickable */
}

 

적용

/* modal */

.modal {
  display: block;
  /* position: relative; */
  pointer-events: none;
  /* background clickable */
}

.modal-backdrop {
  /* display: block; 검은색레이어*/
  display: none;
  /* background clickable */
}

#myModal {
  /* 배경 */
  width: 100%;
  height: 100%;
}

.modal-dialog {
  padding: 10px;
  /* 팝업창 넓이: 특정 DIV에 맞출 것 */
  /* 팝업창 높이: 특정 DIV에 맞출 것 */
  position: fixed;
  /* 팝업창 초기 위치 */
  /* 팝업 닫기 전 위치도 저장해둘 것*/
  top: 12px;
}

.modal-content {
  padding: 0px;
}
728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

ECMAScript에는 입출력에 관한 규정이 없어 각각의 JS 실행 환경이 독자적으로 구현하고 있습니다. 따라서 사용하는 실행 환경에 따라 입출력 방법이 달라집니다. 웹브라우저에서 입출력하는 방법과 관련된 사용자 인터페이스인 폼과 같은 HTML 요소와 이 때 필요한 이벤트 처리기 등록 방법, DOM의 기초를 다룹니다. 또한 HTML5 구성요소로 추가된 Canvas로 기초적인 컴퓨터 그래픽스도 다룹니다.

 

 

 

 

 

1. 대화상자 표시하기


웹 브라우저에 내장된 대화상자(modal 창)를 활용해 입출력을 해보겠습니다. 웹 브라우저의 전역 객체인 Window에는 대화상자를 표시하는 메서드 alert, prompt, confirm 3가지가 있습니다. 대화상자가 떠 있는 중에는 부모창의 작업이 일시정지 되어 조작할 수 없으며, window. 부분은 생략 가능합니다.

 

alert() : 경고

alert("토스트는맛있다");

 

prompt() : 입력칸 표시. 반환값은 문자열

prompt("입력ㄱㄱ");

 

confirm() : 확인/취소버튼이 있는 대화상자. 확인은 true, 취소는 false 반환

prompt("입력ㄱㄱ");

 

 

 

2. Console


Console 객체의 메서드로 콘솔에 값을 출력할 수 있습니다. 프로그램 동작확인과 디버깅에 자주 사용되며 웹 브라우저와 Node.js를 포함한 다양한 JS 실행 환경에서 사용할 수 있습니다. Console 객체의 주요 메서드는 아래와 같으며, 부모창의 동작을 간섭하지 않습니다.

 

console.dir : 객체의 대화형 목록 출력

console.error : 오류 메세지 출력

console.info : 메시지 타입 로그를 출력

console.log : 일반 로그를 출력

console.time : 처리 시간 측정용 타이머 시작

console.timeEnd : 처리시간 측정용 타이머를 정지시키고 타이머를 시작한 후 흐른 시간을 밀리초 단위로 출력

console.trace : 스택 트레이스 출력

console.warn : 경고 메시지 출력

 

 

Console 객체의 메서드에서 사용할 수 있는 서식 문자열

 

서식 문자열 설명 주의사항
%o 객체를 가리키는 하이퍼링크로 변환 Node.js는 미지원
%d 정수값으로 변환 Node.js는 숫자로 변환
%i 정수값으로 변환 Node.js는 미지원
%s 문자열로 변환  
%f 부동소수점 값으로 변환 Node.js는 미지원

 

 

 

3. 이벤트 처리기 등록과 타이머


타이머를 이용하면 슬라이드 쇼나 애니메이션처럼 일정 시간마다 동작을 반복하는 처리를 구현할 수 있습니다.

웹 브라우저에서 동작하는 프로그램은 기본적으로 이벤트 주도형 프로그램 입니다. (event driven program)

이벤트는 단말기와 애플리케이션이 처리할 수 있는 동작이나 사건을 뜻하고, 이벤트 주도형 프로그램은 이벤트가 발생할 때까지 기다렸다가 이벤트가 발생하면 미리 등록해 둔 작업을 수행하는 프로그램입니다.

이벤트 처리기는 이벤트가 발생했을 때 실행되는 함수입니다. 함수를 이벤트 처리기로 등록하는 방법은 HTML 요소의 속성으로 등록하는 법, DOM 요소의 프로퍼티로 등록하는 법, addEventListener 메서드를 사용하는 법이 있습니다.

 

HTML 요소의 속성으로 등록

<.... onclick="함수">

 

DOM 요소의 프로퍼티로 등록

DOM(Document Object Model)은 프로그램이 HTML 요소를 조작할 수 있게 하는 인터페이스입니다. DOM의 주요 객체는 Window와 document가 있으며 window 객체는 윈도우 하나 또는 탭 하나를 가리키며 document 객체는 HTML 문서 전체를 가리킵니다. HTML 문서에서 HTML 요소 객체를 가져오거나 새로 만드는 등 HTML 문서 전반에 걸친 기능을 제공합니다. 요소 객체는 HTML 문서의 요소를 가리킵니다.

window.onload = function(){...};
var button = document.getElementById("button");
button.onclick = displayTime;

// 리터럴로
button.onclick = displayTime(){
	var d = new Date();
	console.log("현재 시각은 " + d.toLocalString()+ "입니다");
};

 

window.onload에 초기 설정 함수를 이벤트 처리기로 등록하고, getElementById 메서드로 요소 객체를 가져온 후 이벤트 처리기 프로퍼티에 이벤트 처리기로 동작할 함수를 등록합니다. 이벤트 처리기 함수는 함수 리터럴로 직접 대입 가능하며 식별할 수 있는 이름을 붙이면 디버깅에 유리해집니다.

 

이벤트처리기 제거 

console.log(button.onkeydown); //null
button.onclick = null;

 

이벤트 처리기가 등록되지 않은 이벤트 처리기 프로퍼티에는 기본적으로 null이 담겨 있기에, 등록한 이벤트 처리기를 제거할 때는 null을 대입합니다.

 

 

타이머

웹브라우저의 Window 객체에는 setTimeout과 setInterval 메서드가 있습니다. 두 함수는 첫번째 인수로 문자열을 넘길 수도 있는데, 이 때 문자열은 내부적으로 eval() (문자열을 코드로 인식하게 하는 함수)로 평가된 후 실행됩니다.

 

setTimeout : 일정 시간이 흐른 후 한번만 함수 실행

// 2초 후 날짜 표시
setTimeout(function(){
	console.log(new Date());  //실행하려는 함수의 참조
}, 2000); // 지연 시간
// 함수 실행 취소
var timer = setTimeout(function() {...}, 2000);
...
clearTimeout(timer);

 

setInterval: 일정 시간마다 반복해 함수 실행

setInterval(function(){
	console.log(new Date()); //실행하려는 함수의 참조
}, 1000); // 시간 간격
// 1초마다 날짜가 표시
// 함수 실행 취소
var timer = setInterval(function() {...}, 1000);
...
clearTimeout(timer);

 

 

 

 

 

4. HTML 요소를 동적으로 읽고쓰기


innerHTML 프로퍼티 활용의 예시 : 스톱워치

<p id = "display">
0.00
</p>
<input id = "start" type="button" value="start">
<input id = "stop" type="button" value="stop">
window.onload = function(){
	var startButton = document.getElementById("start");
	var stopButton = document.getElementById("stop");
	var display = document.getElementById("display");
	var startTime, timer;
	
	startButton.onclick = start; // 버튼 활성화
	
	function start(){
		startButton.onclick = null; // 버튼 비활성화
		stopButton.onclick = stop; // 버튼 활성화
		startTime = new Date();
		timer = setInterval(function(){
			var now = new Date();
			display.innerHTML = ((now-startTime)/1000).toFixed(2);
			},10);
		}
		function stop(){
			clearInterval(timer);
			startButton.onclick = start;
		}
	};

    

 

 

 

폼 컨트롤의 입력 값 사용 : 체질량지수 계산하기

각 폼 컨트롤 요소에 대응하는 요소 객체의 프로퍼티는 아래와 같습니다.

요소 type 속성의 값 프로퍼티 설명
input number, text 등 value 입력된 값을 문자열로 변환한 값
checkbox, radio checked 항목의 선택 여부를 뜻하는 논리값
select - selectedIndex 선택된 option 요소를 가리키는 0부터 시작하는 번호
textarea - value 입력된 문자열

 

<!DOCTYPE html>
<html>

  <head>
    <script>
      window.onload = function() {
        document.getElementById("button").onclick = function() {
          // input 요소에 입력된 데이터를 가져옵니다
          var h = parseFloat(document.getElementById("height").value);
          var w = parseFloat(document.getElementById("weight").value);
          // 체질량지수를 bmi라는 id를 가진 요소(output)에 기록
          var bmi = document.getElementById("bmi");
          bmi.innerHTML = (w / h / h).toFixed(1); //소수점 자르기
        };
      };

    </script>
  </head>

  <body>
    <p>키: <input type="number" id="height"> m</p>
    <p>몸무게: <input type="number" id="weight"> kg</p>
    <p>당신의 체질량지수는 <output id="bmi"> ? </output> 입니다</p>
    <input type="button" id="button" value="계산">
  </body>

</html>

 

 

 

 

document.write

인수로 받은 문자열을 HTML 문서의 body 요소 안에 출력합니다. 웹 브라우저가 HTML 문서를 해석하는 도중에 document.write를 실행하는 점에 유의합니다. 앞의 예제처럼 body 태그 부분이 해석된 후 스크립트 요소가 해석되지 않습니다. 웹브라우저는 script 요소 안 작업이 끝난 후 </body> 다음 부분을 해석해 추가합니다. 

또 이벤트 처리기로 등록한 함수 내에서 document.write를 사용하면 안됩니다. 사용할 경우 이벤트 처리기가 실행되면 HTML 문서 전체 내용이 document.write가 출력한 값으로 바뀝니다. document.write를 사용한 후 호출한 함수에서는 HTML문서를 동적으로 수정할 수 없기에 동적으로 HTML문서를 변경하려면 DOM을 사용해야 합니다.

 

 

 

 

5. Canvas를 활용한 컴퓨터 그래픽


Canvas는 웹브라우저에서 그래픽을 처리하기 위해 추가된 HTML5 구성요소로, Apple 사가 macOS와 사파리 웹브라우저에서 사용자 인터페이스를 만들기 위해 위젯이나 이미지를 렌더링할 목적으로 개발되었습니다. 주요 웹 브라우저에서 사용가능하며 IE에서는 IE9부터 사용 가능합니다. 캔버스로 2차원그래픽과 WebGL을 사용한 3차원 그래픽을 구현할 수 있습니다. 여기에서는 2차원 컴퓨터 그래픽스 기본을 살펴봅니다.

 

Canvas의 특징

Canvas의 특징은 즉시 실행형 저수준 API라는 것입니다. 선, 원, 사각형을 그리는 등 기본적인 그리기 기능 (저수준) 만 제공하기에 속도가 빠릅니다. 또한 Canvas의 그리기 명령은 호출 즉시 실행됩니다. 그림 상태를 저장하는 중간 데이터 계층이 없습니다.

다음 예제는 기본적인 사용법을 보여줍니다. canvas 요소는 ctx.canvas 프로퍼티로도 참조 가능합니다.

 

<canvas id='mycanvas' width='640' height = '400'></canvas>
window.onload = function(){
// canvas 요소 가져오기
	var canvas = document.getElementById("mycanvas");
  // 렌더링 컨텍스트 가져오기
  var ctx = canvas.getContext("2d"); 
  //좌표, 너비, 높이 순
  ctx.strokeRect(50, 60, 200, 100);
  
}

 

 

CSS로도 Canvas의 크기를 설정 가능하지만 브라우저에 따라 왜곡, 확대, 축소될 수 있어서 HTML 속성이나 DOM으로 설정합니다. Canvas의 내장 그리기 기능은 사각형 하나뿐이라 나머지 도형은 패스로 정의해서 그립니다.

 

ctx.strokeRect(10,10,200,150); //사각형 테두리
ctx.fillRect(50, 40, 120, 90); //사각형 채우기
ctx.clearRect(90, 65, 40, 40); //사각형 영역 삭제, 투명화

 

 

패스로 그리기

 

메서드  
moveTo 지정된 좌표로 이동 (선을 그리지 않는 패스만 정의)
lineTo 현재 좌표에서 지정된 좌표까지 선을 정의
arc 원호를 정의
arcTo 현재 좌표까지 원호 정의
rect 사각형 정의
quadraticCurveTo 현재 좌표까지 이차 곡선 정의
bezierCurveTo 현재 좌표까지 베지어 곡선 정의 ( n 개의 점으로부터 얻어지는 n-1 차 곡선)

 

* 삼각형 그리기

<canvas id='mycanvas' width='640' height = '400'></canvas>
window.onload = function() {
  // canvas 요소 가져오기
  var canvas = document.getElementById("mycanvas");
  // 렌더링 컨텍스트 가져오기
  var ctx = canvas.getContext("2d");

  ctx.beginPath();
  ctx.moveTo(60, 10);
  ctx.lineTo(110, 100);
  ctx.lineTo(10, 100);
  ctx.closePath();
  ctx.stroke();

  // 삼각형 채우기
  ctx.beginPath();
  ctx.moveTo(60, 120);
  ctx.lineTo(110, 210);
  ctx.lineTo(10, 210);
  ctx.fill();
}

 

 

 

* 원호 그리기

 

arc(x, y, radius, startAngle, endAngle, anticlockwise)
// 도 단위 각도를 라디안 단위 각도로 변환하는 공식
degress * Mat.PI / 180 

 

window.onload = function() {
  // canvas 요소 가져오기
  var canvas = document.getElementById("mycanvas");
  // 렌더링 컨텍스트 가져오기
  var ctx = canvas.getContext("2d");

  // 시계 방향
  ctx.beginPath();
  ctx.arc(100, 100, 80, 30 * Math.PI / 180, 120 * Math.PI / 180, false);
  ctx.stroke();

  // 시계 반대 방향
  ctx.beginPath();
  ctx.arc(100, 100, 80, 30 * Math.PI / 180, 120 * Math.PI / 180, true);
  ctx.stroke();

}

 

 

* 둥근 모서리 그리기

 

// 둥근 모서리 그리기
window.onload = function() {
  // canvas 요소 가져오기
  var canvas = document.getElementById("mycanvas");
  // 렌더링 컨텍스트 가져오기
  var ctx = canvas.getContext("2d");

  // 시계 방향
  ctx.beginPath();
  ctx.moveTo(10, 10);
  ctx.lineTo(200, 10);
  
  ctx.arc(200, 60, 50, -Math.PI / 2, 0, false);
  // 같은 결과
  // ctx.arcTo(250, 10, 250, 160, 50);
  
  ctx.lineTo(250, 160);
  ctx.stroke();

}

 

 

* 둥근 모서리 사각형

 

 <canvas id='mycanvas' width='640' height='400'></canvas>
window.onload = function() {
  // canvas 요소 가져오기
  var canvas = document.getElementById("mycanvas");
  // 렌더링 컨텍스트 가져오기
  var ctx = canvas.getContext("2d");

  strokeRoundedRect(ctx, 10, 10, 100, 80, 10);
  strokeRoundedRect(ctx, 150, 10, 100, 80, 30);
}

function strokeRoundedRect(ctx, x, y, width, height, radius) {
  ctx.beginPath();
  ctx.moveTo(x + radius, y);
  ctx.arcTo(x + width, y, x + width, y + height, radius);
  ctx.arcTo(x + width, y + height, x, y + height, radius);
  ctx.arcTo(x, y + height, x, y, radius);
  ctx.arcTo(x, y, x + width, y, radius);
  ctx.stroke();
}

 

 

 

 

그래픽스 속성 설정하기

사각형을 그리기 전이나 stroke, fill 메서드로 패스를 그리기 전에 설정하면 그림에 반영됩니다. 선의 스타일, 색상 등은 패스 자체에 프로퍼티가 없어 설정할 수 없습니다. strokeStyle과 fillStyle의 프로퍼티 초기값은 검은색입니다. 투명도는 globalAlpha, 두께는 lineWidth으로 설정할 수 있습니다.

 

ctx.strokeStype = "red" 
ctx.fillStyle = "#44ff44";
ctx.globalAlpha = "0.6";
ctx.lineWidth = 2;

 

패스의 종단점 모양은 lineCap 프로퍼티로 설정하며 설정값은 butt, square, round 총 세가지입니다. 패스 정점은 lineJoin 프로퍼티로 설정하며 miter, round, bevel 세가지 종류가 있습니다.

 

 

그림 읽어오기

읽을 수 있는 이미지 리소스는 URL이 가리키는 이미지파일, Canvas로 그린 컴퓨터그래픽스, img 요소 객체, video 요소 객체 등이 있습니다.

drawImage 메서드로 그리려면 이미지를 읽어오는 데 시간이 걸리기 때문에 이미지 객체의 onload 이벤트처리기에 drawImage 호출 함수를 넣습니다. onload는 이벤트처리기를 등록만 하고 함수를 실행하진 않지만, 일반적으로 이미지를 다 읽은 후의 처리를 먼저 등록하고 읽기 작업을 시작하는 편이 좋습니다.

 

var img = new Image();
img.src = "./cat.jpg"; 
ctx.drawImage(img, 0, 0);
img.onload = function(){
	ctx.drawImage(img, 0, 0);
};
drawImage(image, sx, sy, sw, sh, w, y, width, height)
// 원본이미지에서 특정 부분을 잘라 그리기

 

 

 

픽셀 제어하기

 

1. getImageData(x, y, width, height) 

렌더링 컨텍스트에 렌더링된 이미지 안의 점(x,y)를 왼쪽 위 꼭지점으로 하여 width, height가 너비, 높이인 사각형 영역 안으로 imageData를 가져옵니다.

 

var imgData = ctx.getImageData(x, y, width, height);

 

imageData 객체에는 width, height, data 프로퍼티가 있습니다. data 프로퍼티는 이미지의 픽셀 값이 저장된 1차원 배열로 부호 없는 8비트의 정수 배열입니다. RGBA값이 하나씩 RGBA 순서로 저장되어 있습니다. R,G,B,A 값은 부호 없는 0~255 사이의 정수이므로 배열 data의 길이는 4 * width * height입니다.

 

// imageData의 이미지 안에서 (m, n)번째 픽셀의 RGBA 값 구하기
imageData.getRGBA = function(m, n, i){
	return this.data[this.width*4*n + 4*m + i];
};

 

 

2. createImageData(width, height)

새로운 imageData 객체를 생성합니다.

  • createImageData(width, height) : width, height를 너비 높이로 하는 객체가 생성됩니다. 각 픽셀은 투명한 검은색으로 초기화되어 있습니다.
  • createImageData(anotherImageData) : anotherImageData 와 같은 크기의 이미지를 담을 수 있는 imageData 객체를 생성합니다.

 

3. putImageData(imageData, x, y)

ImageData 객체의 이미지를 렌더링 컨텍스트에 그립니다. 인수 x와 y는 그릴 이미지의 왼쪽 위 모서리의 좌표입니다. 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

xsl 파일에 자바스크립트 첨부하기

- template 안에 script 파일 링크를 둔다.

 

 

solution 1

<xsl:template match="/">
    <script src="/.../test.js"></script>
</xsl:template>

 

 

 

solution 2

 

기본 xslt 파일

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 version="1.0">
    <xsl:include href="include.xsl"/>

    <xsl:template match="/">
        <xsl:call-template name="headers"/>
        <bar>
           <xsl:value-of select="root"/>
        </bar>
    </xsl:template>
</xsl:stylesheet>

include.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
   <xsl:template name="headers">
        <script src="/fs/scripts/shipment/shipment.js"></script>
   </xsl:template>
</xsl:stylesheet>

 

 

 

 

how to include script tag in an xsl file?

 

how to include script tag in an xsl file?

I'm working on an old site that uses java and xsl. How can I inculde a script file in an xsl file? Top of the file: stackoverflow.com

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

Local Storage 로컬스토리지를 이용한 간단한 데이터 저장 실습. 참고한 블로그에서는 DB없이 간단한 게시판 만들기 테스트를 해본 좋은 예제를 소개한다.

 


 

HTML5부터 웹의 데이터를 클라이언트에 저장할 수 있는 새로운 자료구조 Web Storage가 추가되었다. Web Storage는 키/값의 쌍으로 데이터를 저장하고 키를 기반으로 데이터를 조회하는 패턴으로, 영구저장소 LocalStorage와 임시저장소 SessionStorage를 가지고 있다. 쿠키와 비슷하지만 개수와 용량의 제한이 없고,쿠키처럼 매번 서버로 전송하지 않아 네트워크 트래픽 비용을 줄여준다. 

 

로컬스토리지 : 사용자(로컬)에 저장하는 임시저장소. 영구적. windows 전역 객체의 LocalStorage라는 컬렉션을 통해 저장, 조회가 이루어진다.

세션스토리지 : 임시적. windows 전역 객체의 sessionStorage라는 컬렉션을 통해 저장, 조회가 이루어진다.

 

// 데이터 저장하기
localStorage.setItem(key, value);

// 데이터 불러오기
localStorage.getItem(key);

// 데이터 삭제
localStorage.removeItem(key)

// 모든 것 삭제
localStorage.clear()

// index에 해당하는 키 소환
localStorage.key(index)

// 저장된 항목의 수
localStorage.length

 

 

 

 

Local Storage를 이용한 데이터 저장


localStorage의 데이터 저장, 소환 문법은 쿠키의 그것과 비슷하다.

// 데이터 저장하기
localStorage.setItem(이름, 저장할 내용);

// 데이터 불러오기
localStorage.getItem(이름);

 

로컬스토리지의 사용방법은 데이터를 저장할 땐 배열을 선언하여 각각의 정보들을 배열의 요소로 추가하고, 한 이름에 대한 정보들은 여러 항목이 있기에 객체로 저장한다.

objArr = [{num:1, title:'test', contents:'blahblah'}, ...]

 

localStorage는 iterable (반복가능한) 객체가 아니어서 키와 값 전체를 얻으려면 배열처럼 다루면 된다.

 

for(let i=0; i<localStorage.length; i++) {
  let key = localStorage.key(i);
  alert(`${key}: ${localStorage.getItem(key)}`);
}

 

 

 

 

참고

 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

 z-index 속성이 먹히지 않는다면 그 이유는? z-index와 같이 써줘야 할 속성 position 과 기타 규칙들에 대해 알아보자.

 

 

z-index는...

  • z-index는 position 속성이 설정된 element에 대해서만 의미를 갖는다.
  • z-index의 속성은 0, 양수(1 ~ 9999), 음수(-1 ~ -9999) 정수값을 가지며 z축상의 위치를 나타낸다.
  • 숫자가 커질수록 가장 위에 쌓이며 기본 레이어는 0이다.

 

 

 

 

* z-index가 없는 경우 쌓임 규칙

 

 

  1. 뿌리 엘리먼트의 배경과 테두리
  2. 자식 엘리먼트들은 HTML에서 등장하는 순서대로 
  3. position이 지정된 자식 엘리먼트들은 HTML에서 등장하는 순서대로 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

 

 

 

 

▼ 지속적으로 업데이트 중인 곳

 

devJang/developer-roadmap

2020년 웹 개발자가 되기 위한 로드맵 :kr:. Contribute to devJang/developer-roadmap development by creating an account on GitHub.

github.com

 

더보기

* 개발레시피 youtube : https://www.youtube.com/channel/UC516FbDUXu_-vIZwdfayK0w

1. ECMA Script : https://lessipe.com/course/12 

2. npm : https://lessipe.com/course/13 

3. webpack : https://lessipe.com/course/14 

4. vue.js 기초 : https://lessipe.com/course/15 

이 순서로 따라가보시는것도 하나의 방법이 될 것 같습니다.

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,
728x90
728x90

아래 두 슬라이드쉐어 프로젝트에서 발췌했습니다.

 

 

 

웹 Front-End 실무 이야기

프론트엔드와 실무 경험담을 위주로 설명한 프레젠테이션입니다.

www.slideshare.net

 

 

퍼블리셔, 프론트엔드개발을 시작하다

2016 년 하드코딩하느사람들 세미나 발표자료 입니다.

www.slideshare.net

 

 

 

# 1. 웹 프론트엔드 실무 이야기

 

 

 

프로토타이핑 [ prototyping ] : 소프트웨어 시스템이나 컴퓨터 하드웨어 시스템을 본격적으로 생산하기 전에 그 타당성의 검증이나 성능 평가를 위해 미리 시험삼아 만들어 보는 모형제작방법.  [네이버 지식백과] 프로토타이핑 [prototyping] (두산백과)

 

 

 

 

 

# 2. 퍼블리셔, 프론트엔드 개발을 시작하다

 

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,

v