alert

<!DOCTYPE html>
<body>
    <button id="btn" onclick="alertfunc()">button</button>
    <script>
        function alertfunc(){
            alert('hello!');
        }
    </script>
</body>
</html>

 

confirm

<!DOCTYPE html>
<body>
    <button id="btn" onclick="confirm_func()">button</button>
    <script>
        function confirm_func() {
            if(confirm('are you sure?')) {
                alert('yes');
            } else {
                alert('no');
            }
        }
    </script>
</body>
</html>

 

prompt

<!DOCTYPE html>
<body>
    <button id="btn" onclick="prompt_func()">button</button>
    <script>
        function prompt_func() {
            if(prompt('please write what you want to eat') == 'apple') {
                alert('oh here you are');
            } else {
                alert('have to buy other market');
            }
        }
    </script>
</body>
</html>

 

이 에러.. 왜 나타나는 걸까?

 

그 이유는 바로 js 코드의 위치 때문이다. html 파일은 위에서부터 순서대로 코드를 로드하기 때문에, 만약에 다음과 같이 코드를 작성한다면 오류가 날 수 밖에 없다.

 

index.html

<!DOCTYPE html>
<head>
    <script src="./script.js"></script>
</head>
<body>
    <button id="btn">button</button>
</body>
</html>

script.js

var btn = document.getElementById('btn');
btn.addEventListener('click', function() {
    alert('hello!');
})

문제는, javascript 코드가 html코드의 button 태그를 호출하고 있다는 점에서부터 시작이된다. 그 이유는 javascript 코드가 html 코드보다 위에 작성되어서 먼저 호출이 되는데, 아직 button 태그가 호출되지 않은 상태에서 button 태그를 가져오고 있기 때문이다.

 

해결법

<!DOCTYPE html>
<head>
    <script>
        window.onload = function() {
            var btn = document.getElementById('btn');
            btn.addEventListener('click', function() {
            	alert('hello!');
        	})
        }
    </script>
</head>
<body>
    <button id="btn">button</button>
</body>
</html>

window 객체의 onload 메소드는, html 코드가 모두 로드된 이후에 javascript 코드를 로드하라는 의미이다.

 

<!DOCTYPE html>
<body>
    <button id="btn">button</button>
    <script src="./script.js"></script>
</body>
</html>

그러나 window.onload 를 사용하는 것보다 body 태그 마지막부분에 script 태그를 추가하는 것이 더 좋은 방법이다. 그 이유는 onload의 경우 페이지를 로드하다가 중간에 멈추기 때문이다. javascript 코드를 건너뛰고 html 부터 로드하기 때문에 성능면에서 떨어지기 때문이다.

inline code

다음과 같은 코드가 있다고 하자.

<!DOCTYPE html>
<body>
    <button onclick="alert('hello!')">button</button>
</body>
</html>

이 코드에 문제점이 있을까?

이 코드의 장점이자 단점은 바로 html코드가 javascript코드와 함께 공존한다는 것이다. 이것이 좋은 이유는 함께 있기 때문에 제어도 바로바로 할 수 있다는 것이다. 그러나 이 장점에 비해 단점이 크기 때문에 추천하지 않는 방식이다. 만약, 제어의 코드(javascript)가 더 많이 늘어난다면? 변수도 지정하는 등의 복잡한 로직을 처리한다면? 결정적으로, 정보와 제어가 분리되지 않은 것이 가장 큰 문제이다.

 

그렇다면, html 코드와 javascript를 분리하는 방식들을 살펴보자.

script tag

<!DOCTYPE html>
<body>
    <button id="btn">button</button>
    <script>
        var btn = document.getElementById('btn');
        btn.addEventListener('click', function() {
            alert('hello!');
        })
    </script>
</body>
</html>

 

외부파일로 분리

script.js

var btn = document.getElementById('btn');
btn.addEventListener('click', function() {
    alert('hello!');
})

index.html

<!DOCTYPE html>
<body>
    <button id="btn">button</button>
    <script src="./script.js"></script>
</body>
</html>

이러한 방식으로 외부 파일로 분리한다면 "유지보수의 편의성"의 방면에서 용이해진다. 하나의 자바스크립트는 여러 개의 html 파일에서 활용이 될 수도 있기 때문이다. 일반적으로, 코딩에 있어서 응집력은 높히고 결합도는 낮춰야 한다. javascript 파일을 외부 파일로 기능별 분리를 한다면 자연스럽게 코드 간의 결합도는 낮아지고 기능 별 응집도는 높아질 것이다.

>> 이 문서는 다음 글을 번역한 것입니다.
https://www.npmjs.com/package/nativescript#what-is-nativescript

 

네이티브 스크립트란?

네이티브 스크립트는 네이티브 iOS 와 Android 앱을 단 하나의 코드 기반으로 개발하도록 도와주는 cross-platform JavaScript framework 이다. 이 프레임워크는 자바스크립트가 iOS 와 Android 의 네이티브 API, UI 그리고 렌더링 엔진에 접근하도록 도와준다. 자바스크립트(혹은 타입스크립트)를 사용하면 완전히 네이티브 사용자 환경을 가진 iOS 또는 Android 앱으로 만들어진 하나의 프로젝트를 만들 수 있다.

 

 

 

 

 

NativeScript CLI(Command-line interface)가 동작하는 방식

NativeScript CLI는 NativeScript를 동작하기 위한 방법이다. 이는 몇가지 중요한 서비스들을 통합했다.

Commands 명령어를 입력하고 수행한다.
Devices Service NativeScript 와 기기/에뮬레이터/시뮬레이터를 연결시켜준다..
LiveSync Service 개발 중 코드가 변경될 때 응용 프로그램을 재배포해준다.
Hooks Service 개발된 앱에서 사용자 정의 hook를 실행시킴으로써 빌드 프로세스를 수정한다.
Platform Service 앱 빌드 편의기능을 제공하고 Gradle을 사용하여 Android Package나 Xcode를 빌드한다.

 

 

 

 

 

NativeScript CLI 설치방법

node.js의 npm을 이용하여 설치한다.

// NativeScript 설치 명령어
npm install nativescript -g

// 제대로 설치되었는지 확인하기 위한 명령어
ns doctor

 

 

 

 

 

프로젝트 생성하기

// javaScript로 프로젝트 생성하기
ns create MyApp --js

// typeScript, angular, vue로 프로젝트 생성하기
ns create MyApp --template typescript
ns create MyApp --template angular
ns create MyApp --template vue

// 위 작업은 간단한 옵션으로도 처리 가능하다.
ns create MyApp --tsc
ns create MyApp --ng

 

 

 

 

템플릿 설정하기

ns create MyApp --template <template-package-name>

 

 

 

 

 

템플릿 종류

Blank

ns create MyApp --template @nativescript/template-blank

Drawer

na create MyApp --template @nativescipt/template-drawer-navigation

Tabs

ns create MyApp --template @nativescript/template-tab-navigation

List and Details

ns create MyApp --template @nativescript/template-master-detail

json

JSON 이란

서버와 데이터를 주고받기위한 방식 중 하나이다.

이 때 서버와 통신하게 되는 데이터 오브젝트는 키와 값의 쌍으로 이루어져있다.

데이터를 저장할 때는 string 형태로 데이터를 저장하게 되고,

다시 데이터를 가져올 때는 string 형태의 데이터를 다시 object 로 변환하여 준다.

 

json을 사용하기 위한 대표적인 두 가지 함수

1. stringify

이름에서도 유추해볼 수 있듯이, 데이터를 string 화 해준다. 즉 데이터를 저장하기 위함이다.

// script.js
let json = JSON.stringify(["person-name", "person-age"]);
console.log(json);

// 결과 화면

stringify 에 전달한 내용이 출력되는 것을 볼 수 있다.

이번에는 객체를 저장해보자.

// json.js
const you = {
    name: 'right',
    age: 26,
    height: 174,
    birthDate: new Date(),
    talk: () => {
        console.log(`${this.name} : say something ...`);
    }
}
json = JSON.stringify(you);
console.log(json);

// 결과 화면

함수는 전달되지 않는다는 사실을 알 수 있다.

 

 

1. parse

string화 되어있는 데이터를 객체 형태로 다시 불러와 준다. 즉 데이터를 불러오기 위함이다.

// script.js
json = JSON.stringify(you);
const obj = JSON.parse(json);
console.log(obj);

// 하지만 함수는 전달되지 않는다.
json.talk();
obj.talk();

 

 

0. 개요

 먼저 자바스크립트는 기본적으로 동기적으로 운영된다는 것을 알아야한다. 그러나 그런 자바스크립트에게 비동기적으로 처리할 수 있는 방식들이 세가지가 있었는데, 그 중 하나는 Callback 함수를 이용하는 것이었다. 그러나 콜백함수를 이용하게 되면 일명 "콜백 지옥"에 빠질 수 있는 위험성이 있다. 그래서 콜백 함수 대신에 비동기적으로 자바스크립트를 처리하기 위한 방법 중 하나가 바로 프로미스이다.

>> 이전 포스팅을 먼저 본다면 이해에 도움이 된다.

자바스크립트에서 비동기 처리란?
https://jinn-o.tistory.com/24

비동기적 Callback 함수 이용하기
https://jinn-o.tistory.com/25

 

 

 

1. 그래서 프로미스가 뭔데?

프로미스, 즉 Promise 한국어로 약속이라는 의미이다. 상당히 미래지향적 단어임을 눈치챘다면, 맞다. 프로미스는 비동기 작업이 미래에 성공할 것인지, 실패할 것인지의 결과 값을 나타낸다.

 

 

 

2. 프로미스의 4가지 상태값

Pending : 아직 결과 값이 반환되지 않은 대기 중인 상태

Fulfilled : 성공

Rejected : 실패

Settled : 결과 값이 성공 혹은 실패로 반환된 상태

 

 

 

3. 프로미스 생성자 예제

먼저 resolve 의 경우 (성공하는 경우)의 코드를 살펴보자.

const promise = new Promise((resolve, reject) => {
	console.log('doing something ... ');
    setTimeout(() => {
    	resolve('success!');
    }, 2000);
});

new 를 통해 생성자를 생성하고, 작업을 수행한 뒤에 만약에 작업 수행이 성공하면 2초뒤에 success!를 반환하는 코드를 작성하여 보았다.

 

 

다음으로 reject 의 경우 (실패하는 경우)의 코드를 살펴보자.

const promise = new Promise((resolve, reject) => {
	console.log('doing something ... ');
    setTimeout(() => {
    	reject(new Error('no network'));
    }, 2000);
});

 

 

 

 

4. 프로미스 사용자 예제

프로미스를 호출할 때는 then 과 catch 그리고 finally 메소드가 있다.

먼저, then 같은 경우에 사용법은 다음과 같다.

promise.then(value => {
	console.log(value);
});

여기서 then 이란 resolve, 즉 성공했을 때의 인자를 받아온다.

따라서 콘솔에 찍히는 결과값은 다음과 같다.

// resolve => then 결과값
success !

 

 

다음으로 실패했을 경우인 catch 같은 경우에 사용법은 다음과 같다.

성공할 경우에다가 catch 를 붙이면 실패할 경우에는 어떻게 대처하는 지에 대한 메뉴얼이 된다.

promise
    .then(value => {
    	console.log(value);
    })
    .catch(error => {
    	console.log(error);
    });

콘솔에 찍히는 결과값은 다음과 같다.

// reject => catch 결과값
Error: no network

 

 

 

마지막으로 finally 는? 바로 성공하든 실패하든 마지막에 실행되는 메소드이다.

 

promise
    .then(value => {
    	console.log(value);
    })
    .catch(error => {
    	console.log(error);
    })
    .finally(() => {
    	console.log('finally');
    });​

성공했을 때의 결과값

success !
finally

실패했을 때의 결과값

Error: no network
finally

Call Back 함수란?

함수를 매개변수로 받아서 함수 안에서 함수를 호출하는 것을 말한다. 내부에 있는 함수의 Call(요청)에 대한 Back(응답)을 받아야 상위 함수도 동작할 수 있기에, 이렇게 데이터가 엮여있기 때문에 콜백함수라고 말한다.

 

그런데 Call Back 함수가 비동기적이라고?

특정한 요청을 보내면, 해당 요청에 대한 응답을 기다리는 동안 다른 나머지 코드들을 실행하는 것을 말한다.

그러니까, 원래 동기적으로 동작하면서 순차적으로 코드를 실행하는 것이 자바스크립트의 원래 모습인데, 콜백 함수를 이용하면 무조건 작업이 끝난 다음에 다음 코드가 실행되는 것이 아니라, 요청을 보내놓고 다른 일을 하다가 호출하는 것이다. 물론 콜백함수는 동기적으로도 불러올 수 있다.

// 동기적 콜백 Synchronous Callback

function printImmediately(print) {
	print();
}
printImmediately(() => console.log('Hello'));





// 비동기적 콜백 Asynchronous Callback

function printWithDelay(print, timeout) {
	setTimeout(print, timeout);
}
printWithDelay(() => console.log('async callback'), 2000);

 

 

 

콜백지옥! 들어봤는가?

함수 내부에 콜백함수를 부르고, 또 그 내부에 콜백함수를 부르고, 또 부르고 ... 를 반복하다보면 계속 콜백이 되기 때문에 콜백 지옥이 만들어진다. 따라서 복잡한 코드에서 콜백함수를 많이 호출하는 것을 권유하지 않는다.

 

0. Single Thread 언어인 Javascript

 먼저 자바스크립트는 Single Threaded 언어이다. 즉, 하나의 프로세스에서는 하나의 쓰레드만이 존재한다는 것이다.

운영체제를 배웠다면, 프로세스와 쓰레드에 관한 개념을 이해하기 쉬운데, 배우지 않았다면 다음 예시를 살펴보자.

멀티 쓰레딩의 의미는 하나의 프로세스가 여러가지의 작업을 할 수 있다는 의미이다. 사람으로 친다면, 한 손으로는 커피를 마시고 다른 손으로는 신문을 보고 다리로는 걷는 일을 동시에 하는 것처럼 하나의 프로세스가 여러 가지의 일을 할 때 멀티 쓰레딩하다고 한다. 그렇다면 이제 싱글 쓰레딩이 뭔지 이해가 될 것이다. 그렇다. 단 하나의 작업만 수행할 수 있는 것을 의미한다.

 

 그러나 자바스크립트가 Multi Threading 하게 아예 동작할 수 없는 것은 아니다. 실제로 웹 페이지에서 동시에 여러 작업을 할 수 있었던 경험이 있을 것이다. 이 때 이용하게 되는 것이 웹 APIs 이다. 이를 이용하게 되면 자바스크립트도 멀티 쓰레딩한 것처럼 동작이 가능하다.

 

다음은 MDN 사이트에 명시된 Web APIs 이다.

https://developer.mozilla.org/ko/docs/Web/API

 

Web API | MDN

웹 코드를 작성한다면 많은 API를 사용할 수 있습니다. 아래 목록은 웹 앱이나 웹 사이트를 만들 때 사용할 수 있는 모든 인터페이스(객체의 유형)입니다.

developer.mozilla.org

 

 

 

1. 자바스크립트는 기본적으로는 동기적(synchronous)으로 동작한다 !

"동기적으로 동작한다." 의 의미는 "먼저 수행된 작업이 모두 끝나고 나서야 다음 일을 순차적으로 수행하는 것"이고

"비동기적으로 동작한다." 의 의미는 "요청을 다같이 보내고 작업이 끝나지 않아도 다음 동작을 수행하는 것"이다.

이처럼 자바스크립트는 호이스팅(hoisting)을 이용하여 기본적으로 동기적으로 동작하는 데, 문제는 비동기적으로 처리할 수 있는 방법이 존재하기 때문에 자바스크립트에서 비동기 처리 이슈가 있는 것이다.

 

1.5 호이스팅(hoisting)이란?

자바스크립트는 호이스팅(hoisting)을 이용해서 var 변수나 function 함수를 제일 위로 올려서 선언문들을 차례대로 먼저 수행한다. 이 때 할당은 같이 끌어올려지지 않는다. 즉, 알맹이는 냅두고 겉껍질만 일단 선언해놓는 것이다. 예를 들어, 어떤 모임에 사람들이 모이기 전에 출석체크부터 하는 것과 같은 맥락이라고 보면 된다.

 

 

 

2. 그래서 자바스크립트로 비동기 처리를 어떻게 하는 건데?

크게 세 가지의 방법이 있다.

 

첫 째, 비동기적 Call Back 함수 이용하기

https://jinn-o.tistory.com/25

 

비동기적 Call Back 함수 이용하기

Call Back 함수란? 함수를 매개변수로 받아서 함수 안에서 함수를 호출하는 것을 말한다. 내부에 있는 함수의 Call(요청)에 대한 Back(응답)을 받아야 상위 함수도 동작할 수 있기에, 이렇게 데이터가

jinn-o.tistory.com

 

둘 째, Promise 사용하기

https://jinn-o.tistory.com/26

 

Promise 사용하기 (프로미스가 뭘까?)

0. 개요  먼저 자바스크립트는 기본적으로 동기적으로 운영된다는 것을 알아야한다. 그러나 그런 자바스크립트에게 비동기적으로 처리할 수 있는 방식들이 세가지가 있었는데, 그 중 하나는 Cal

jinn-o.tistory.com

 

셋 째, Async & Await

 

 

 

위 비동기 처리에 관한 세 가지의 방법이 담긴 포스팅은 링크로 달아두었다.

자바스크립트도 typescript 처럼 타입을 부여한 덩어리를 만들 수 있다!

enum class 를 이용한다면 날 것 그대로의 문자열을 사용하지 않고 타입들을 지정할 수 있다.

 

javascript enum class 사용예시

const State = Object.freeze({
    win: 'win',
    fail: 'fail',
    cancel: 'cancel',
});

const StateMessage = Object.freeze({
    win: 'SUCCESS !!',
    fail: 'fail ... replay ?',
    cancel: 'replay ?',
    error: 'not valid state',
});



// enum class 사용 전 코드

function getStateMessage(state) {
	let message;
	switch (state) {
		case 'win':
			message = 'SUCCESS !!';
			break;
		case 'fail':
			message = 'fail ... replay ?';
			break;
		case 'cancel':
			message = 'replay ?'
			break;
		default:
			throw new Error('not valid state');
	}
    return message;
}



// enum class 사용 후 코드

function getStateMessage(state) {
	let message;
	switch (state) {
		case State.win:
			message = StateMessage.win;
			break;
		case State.fail:
			message = StateMessage.fail;
			break;
		case State.cancel:
			message = StateMessage.cancel;
			break;
		default:
			throw new Error(StateMessage.error);
	}
	return message;
}

자바스크립트 빌더 패턴이란?

클래스를 추상화(abstration)하기 위한 방법이다. 빌더 패턴을 사용하면 코드를 더 가독성이 좋게 만들 수 있으며, 클래스를 직접적으로 노출시키지 않고 객체를 생성할 수 있다.

 

 

 

 

 

빌더 패턴 예시

 

class BookBuilder {
	withName(name) {
    	this.name = name;
        return this;
	}
	withPrice(price) {
    	this.price = price;
        return this;
	}
	withPublisher(publisher) {
    	this.publisher = publisher;
        return this;
	}
	build() {
    	return new Book(
        	this.name,
            this.price,
            this.publisher
        );
	}
}

class Book {
	constructor(name, price, publisher) {
    	this.name = name;
        this.price = price;
        this.publisher;
    }
}

위와 같은 코드를 만들었다면 main.js 에서는 다음과 같이 사용한다.

const book = new BookBuilder()
	.withName('InnerWorld')
	.withPrice(15000)
	.withPublisher('Jinn_O')
	.build();

+ Recent posts