민한의 블로그

스터디 1일차 본문

정리하고있는 책들/인사이드 자바스크립트

스터디 1일차

minhan2 2018. 8. 5. 07:00
728x90
반응형


공부하며 궁금한것들은 다 찾아본다.



자바스크립트란?

자바스크립트는 웹 브라우저에서 동작하는 스크립트 언어이다.

(인터프리터 언어라고도 부른다. 인터프린터는 첫번째 줄부터 밑으로 차례대로 해석을 시작한다.)

스크립트(Script) 언어란 소스 코드를 컴파일러를 통해, 기게어 코드로 변환하지 않고, 내장된 번역기에 의해 번역되어 행할 수 있는 프로그래밍 언어를 말한다.

상반되는 언어로는 컴파일러형 언어가 있으며,  컴퓨터에 의해 동작되기전 다른 형식으로 변환하는 언어이다. 예를 들면 C++이나 JAVA와 같은 언어는 어셈블리어로 컴파일되어 동작된다.

스크립트 언어는 소스를 작성한 후 컴파일 과정 없이 바로 실행하여 결과를 확인할 수 있다는 장점이 있는 반면에 번역 과정을 거쳐야 하기 때문에 다소 느리다는 단점이 있다. C언어나 Java와 같은 비스크립트 언어의 경우 실행 속도가 빠른 장점이 있는 반면 컴파일 과정을 거쳐야 하는 등 개발 과정이 조금 복잡하다는 단점이 있다.


~자바스크립트는 JAVA나 C++ 와 같은 클래스기반 객체지향 언어가 아니라, 프로토타입 기반의 객체지향 언어이다.


클래스가 없으니 기본적으로 상속기능도 없습니다. 그래서 보통 프로토타입을 기반으로 상속을 흉내내도록 구현해 사용합니다.


참고로 최근의 ECMA6 표준에서는 Class 문법이 추가되었습니다. 하지만 문법이 추가되었다는 것이지, 자바스크립트가 클래스 기반으로 바뀌었다는 것은 아닙니다.





옛날에는 가장 무시당하고 있던 언어였다.


초창기 자바스크립트는 웹 페이지 제작에 있어서 보조적인 기능을 수행하기 위한 용도로 사용했다.

대부분의 로직은 주로 웹 서버에서 실행되었고, 클라이언트인 웹 브라우저에서 서버로부터 받은 HTML과 CSS, 데이터로 렌더링을 해주는 수준이였다.

자바스크립트는 중요한 역할을 담당하지 못했다.

하지만 지금은!

~현재는 github의 프로젝트 중에서 가장 많이 사용되고 있는 언어가 자바스크립트 이다.

한국에서는 세계적인 추세와는 달리 자바스크립트에 대한 관심이 외국에 비해 다소 떨어졌었다.

표준을 지키지 않은 IE6에서 초창기 웹 개발이 이루어지다 보니, 여러 웹분야에서 뒤쳐졌으나, 최근에는 많은 웹개발자들이 자바스크립트를 다시 보는 움직임이 있다.







변천사 

1995년, 당시 네스케이프사의 네비게이터가 웹브라우저 시장을 지배하고 있었는데, 네스케이프는 HTML페이지에 경량의 프로그램 언어를 통하여 인터렉티브한 것을 추가 하기로 결정했다.

그래서 Brendan Erich를 고용했다., 그는 10일 만에 언어를 만들었다.

그 언어의 이름은 ‘모카’였고, 9월 ‘라이브스크립트’로 이름을 변경하였다.

자바스크립트는 왜 ‘ECMAScript’라 불리게 되었나?

자바스크립트가 나온 이후 , MS사는 IE 3.0에서 동작하는 ‘JSrcipt’라는 똑같은 언어를 만들어 냈다.그러자 넷스케이프사는 자바스크립트를 표준화 하기 위해, 표준화 기구인 Ecma International에 요청을 했다.1996년 11월, ECMA-262라 불리는 명세서에 대한 작업이 시작했고 그 버전은 1997년 7월에 완성되었다.당시 Sun사가 ‘JAVA‘라는 단어를 상표 등록을 해 놨기에 ‘JavaScript’라고 부를 수 없었다.

 표준 언어의 이름은 ECMAScript이고,대외적으로 알리기 위해서 자바스크립트나 J스크립트라고 불렀다. 나중엔 표준 이나 구현 모두 ‘JavaScript’라는 이름으로 불렸다.



(그림출처 : https://medium.com/sfl-newsroom/ecmascript-from-roots-to-ecmascript-2017-ce92afc96447)




왜 ES2015 이상의 내용을 얘기할 때 ES를 쓰냐면 ES5와 ES2015 사이에 너무나 큰 변화가 있었기 때문이다.


ES3 (1999)

대중적으로 알고있는 그냥 자바스크립트라고 보면 된다. 함수 단위의 스코프호이스팅클로저프로토타입 등… 우리가 익히 알고있는 자바스크립트의 기본적인 특징들을 갖고있다. 대부분의 브라우저에서 지원하며, IE8까지 크로스브라우징을 지원하는 환경이라면 ES3을 쓰고 있다고 보면 된다.

ES5 (2009)

ES4는 너무 시대의 흐름을 앞서갔는지 거절되고, 그 후에 점진적인 개선을 목표로 ES5가 나왔다고 한다. 아무리 그래도 10년만에 버전업이라니 너무한것 같지만 ㅁ낳은 편리한 기능이 추가되었다.

    배열 배열과 관련하여 편리한 메소드들이 다수 생겼다. forEachmapreducefiltersomeevery와 같은 순환 메소드들이 생겼다. 이 메소드들은 개발 시 불필요한 중복 코드를 줄여주어서 가독성은 높이고 버그율은 낮추는 효과가 있다.

    객체 객체는 프로퍼티에 대한 설정을 할 수 있게 되었다. 객체를 생성, 수정, 복사하는 표준 메소드 Object.Create()Object.defineProperty()Object.freeze()Object.assign() 등 과 gettersetter 등이 추가되었으며, Object.keys() 메소드를 이용하면 for in 메소드도 대체할 수 있게 되었다.

    strict 모드 문법을 좀 더 깐깐하게 체크하는 모드이다. 너무 자유분방하였던 기존 ES를 안전하고, 개발자가 인지할 수 있는 범위 안에서 개발할 수 있도록 사용하기 위해 등장했다. Strict mode - JavaScript | MDN에서 자세한 특징을 확인 할 수 있다.

    bind() 메소드 this를 강제로 바인딩 시켜주는 메소드이다. 좀 더 명확하게 this 스코프를 지정 할 수 있게 되었다.

ES6 (ES2015)

ES6보다 ES2015라고 많이 불리우며, ES6 Harmony라고도 불리운다고 한다. ES2015에서 다음과 같은 문제점들이 해결되었다.

    호이스팅이 사라진 것 같은 효과

    함수 단위 스코프에서 블록 단위 스코프로 변경

    this를 동적으로 바인딩하지 않는 화살표 함수

    모듈화 지원

    콜백 지옥에서 구원해줄 Promise

    Default, Rest 파라미터

    해체 할당, Spread 연산자

    템플릿 리터럴

    클래스 이 외에도 추가된점이 너무 많아서 이부분에서 사람들이 진입장벽 느끼게 된다. 

    브라우저(특히 MS 계열. 인터넷 익스플로어)에서 지원해주지 않는 경우가 많아 바벨(Babel)이라는 트랜스파일러( ES2015+ 문법을 사용한 코드를 예전 ES5 자바스크립트 코드로 바꿔주는 도구들이 있습니다. 그중에서 가장 유명한 도구가 바벨입니다.)를 써야하는데 이 바벨은 웹브라우저가 아닌 Node.js 위에서 돌아가고, 

    (Node.js는 Chrome V8 Javascript 엔진으로 빌드된 Javascript 런타임이다. 

    런타임이란 프로그래밍 언어가 구동되는 환경

    예전에는 자바스크립트 런타임이 브라우저 밖에 존재하질 않았다.

    하지만 그러한 한계를 극복하고 Node.js가 나왔다. )

    Node.js를 설치하려면 NPM

    (npm이라는 게 있습니다. node package manager의 줄임말인데요. Node.js에서는 자주 쓰이고 재사용되는 자바스크립트 코드들을 패키지로 만들어서 사용할 수 있습니다. 그러한 패키지를 모아놓은 저장소가 npm입니다.)
    을 알아야하고… 또 모듈화를 사용하려면 웹팩(WebPack)같은 모듈 번들러를 알아야한다.




자바스크립트 데이터 타입과 연산자




( 그림출처 : https://www.dotnettricks.com/learn/stepbystep/Javascript/datatype )


자바스크립트에서의 기본타입은 숫자, 문자열, 불린값을 비롯해 null 과 undefined 라는 타입이 있다.




javascript는 동적 프로그래밍 언어(느슨한 타입 체크 언어)이기에, 선언 할 때 변수의 유형을 선언 할 필요가 없다.

프로그램 실행시 런타임에 타입이 자동으로 결정되기에, 다른 유형(number, string, object...등)에 대해 var

(es6 이전) 라는 한가지 키워드만으로 동일한 변수를 가질 수있다.

 javascript는 어떤 형태의 데이터를 저장하느냐에 따라 해당 변수의 타입이 결정된다.

정적 프로그래밍 언어(엄격한 타입 체크 언어)인 C언어는 변수를 선언할때 변수에 저장할 데이터의 종류(문자, 정수, 실수)에 따라 char, int, float 등의 예약어를 이용해서 변수의 데이터 타입을 지정해야 한다.


    <script>

    var x = 42; // x 는 Number 입니다.

    var x = "DOT NET TRICKS"; // x 는 String 입니다.

    var x = true; // x 는 Boolean 입니다.

    var x = {name:'John', age:34}; // x 는 Object 입니다.

    </script>


자바 스크립트 typeof 연산자는 자바 스크립트 변수의 유형을 찾는 데 사용됩니다.


    <script>

    typeof "John" // returns string

    typeof 3.14 // returns number

    typeof Infinity; // returns number

    typeof NaN; // returns number

    typeof false // returns Boolean

    typeof null // returns object and this is bug in ECMA script5

     

    typeof [1,2,3,4] // returns object

    typeof {name:'John', age:34} // returns object

    typeof function(){} // returns function

    typeof /^[0-9]$/I // returns object

     

    var d = new Date();

    typeof d // returns object

    </script>



자바스크립트에서 숫자, 문자열, 불린값, null, undefined 같은 기본타입을 제외한 모든값은 객체다.

따라서 배열, 함수, 정규표현식 등도 모두 결국 자바스크립트 객체로 표현된다.


자바스크립트에서는 객체는 단순히 '이름(key) : 값 (value)' 형태의 프로퍼티를 저장하는 컨테이너로서, 컴퓨터 과학분야에서 해시라는 자료구조와 상당히 유사하다.



객체 생성


자바에서는 클래스를 정의하고, 클래스의 인스턴스를 생성하는 과정에서 객체가 만들어진다.

자바스크립트에서는 클래스라는 개념이 없고(es6이전), 객체 리터럴이나 생성자 함수 등 별도의 생성 방식이 존재한다.


-Object() 생성자 함수 이용

-객체 리터럴 방식


~객체 프로퍼티 읽기/쓰기/갱신


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 객체 리터럴 방식을 통한 foo 객체 생성
var foo = {
    name : 'foo',
    major : 'computer science'
};
 
// 객체 프로퍼티 읽기
console.log(foo.name); // foo
console.log(foo['name']); // foo
console.log(foo.nickname); // undefined
 
// 객체 프로퍼티 갱신
foo.major = 'electronics engineering';
console.log(foo.major); //electronics engineering
console.log(foo['major']); //electronics engineering
 
// 객체 프로퍼티 동적 생성
foo.age = 30;
console.log(foo.age); // 30
 
// 대괄호 표기법만을 사용해야 할 경우
foo['full-name'= 'foo bar';
console.log(foo['full-name']); // foo bar
console.log(foo.full-name); // NaN
console.log(foo.full); // undefined
console.log(name); // undefined
cs



%참고사항

-만약 객체에 없는 프로퍼티에 접근하는 경우는 undefined 값이 출력된다.

가령 앞 예제 코드에서 foo 객체에 nickname 프로퍼티가 없으므로,

console.log(foo.nickname)

앞 코드의 결과는 undefined 값이 출력된다.

-객체 프로퍼티를 foo['name'] 대신에 foo[name]처럼 따움표를 적지 않으면 undefined 값이 출력된다.

-Javascript 에서 변수 선언 없이 바로 사용하게 되면 비록 함수내의 로컬변수로 사용되더라도 모든 변수들은 암묵적으로 전역 프로퍼티가 되어 버린다.

-Javascipt 에서 NaN(Not a Number)은 수치 연산을 해서 정상적인 값을 얻지 못할 때 출력되는 값이다. 가령, 1 - 'hello'라는 연산결과는 NaN이다. 1이라는 문자열 'hello'를 빼는 연산을 수행했기 때문이다.




~for in 문과 객체 프로퍼티 출력

1
2
3
4
5
6
7
8
9
10
11
12
// 객체 리터럴을 통한 foo 객체 생성
var foo = {
    name'foo',
    age: 30,
    major: 'computer science'
};
 
// for in문을 이용한 객체 프로퍼티 출력
var prop;
for (prop in foo) {
    console.log(prop, foo[prop]);
}
cs

for in 문이 수행되면서 prop 변수에 foo 객체의 프로퍼티가 하나씩 할당된다.

따라서 prop에 할당된 프로퍼티 이름을 이용하여 foo[prop]와 같이 대괄호 표기법을 이용해서 프로퍼티 값을 출력한 것이다.


[출력결과]

name foo

age 30

major 'computer science'


-key value 값을 뽑아내었다.





기본타입과 참조타입의 호출방식 차이


(그림 출처 : https://coloringpagewiki.com/m/c-reference-parameter.asp)

기본타입와 참조타입의 경우는 함수 호출 방식도 다르다.
기본 타입의 경우는 값에 의한 호출(call by value) 방식으로 동작한다.
즉, 함수를 호출할때 인자로 기본 타입의 값을 넘길경우, 호출된 함수의 매개변수로 복사된 값이 전달된다.
때문에 함수 내부에서 매개변수를 이용해, 값을 변경해도, 실제로 호출된 변수의 값이 변경되지는 않는다.

이에 반해 객체와 같은 참조 타입의 경우 함수를 호출할때 참조에 의한 호출(call by reference)방식 으로 동작한다. 즉. 함수를 호출할때 인자로 참조타입인 객체를 전달할 경우, 객체의 프로퍼티값이 함수의 매개변수로 복사되지 않고, 인자로 넘긴 객체의 참조값이 그대로 함수 내부로 전달된다. 때문에 함수 내부에서 참조값을 이용해서 인자로 넘긴 실제 객체의 값을 변경할수 있는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a = 100;
var objA = { value: 100 };
 
function changeArg(num, obj) {
    num = 200;
    obj.value = 200;
 
    console.log(num);
    console.log(obj);
}
 
changeArg(a, objA);
 
console.log(a);
console.log(objA);
 
cs


[출력결과]
200
{ value : 200 }
100
{ value : 200 }


프로토타입

( 그림출처: http://yycjs.com/the-weird-parts)




함수가 정의될 때는 2가지 일이 동시에 이루어집니다.

1.해당 함수에 Constructor(생성자) 자격 부여

Constructor 자격이 부여되면 new를 통해 객체를 만들어 낼 수 있게 됩니다. 이것이 함수만 new 키워드를 사용할 수 있는 이유입니다.


constructor는 Prototype Object와 같이 생성되었던 함수를 가리키고 있습니다.

__proto__는 Prototype Link입니다. 밑에서 자세히 설명합니다.


prototype 속성은 함수만 가지고 있던 것과는 달리(Person.prototype 기억나시죠?) 

__proto__속성은 모든 객체가 빠짐없이 가지고 있는 속성입니다.


__proto__는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킵니다. 









( 그림출처 : http://insanehong.kr/post/javascript-prototype/)


자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있다. 그리고 이것은 마치 객체지향의 상속 개념과 같이 부모객체의 프로퍼티를 자신의 것처럼 쓸 수 있는 것 같은 특징이 있다.

자바스크립트에서는 이러한 부모 객체를 프로토타입 객체(짧게는 프로토타입) 라고 부른다.


ECMAScript 명세서에는 자바스크립트의 모든 객체는 자신의 프로토타입을 가리키는 [[Prototype]] 라는 숨겨진프로퍼티를 가진다고 설명하고 있다. 크롬 브라우저에는 __proto__가 바로 이 숨겨진 [[Prototype]] 프로퍼티를 의미한다.

생성된 객체는 자신의 부모 객체를 __proto__라는 내부 프로퍼티로 연결하고 있는것이다.











참고출처

-인사이드 자바스크립트(서적)

- 오늘도 끄적끄적 : https://blog.perfectacle.com/2017/04/26/js-001-es/#ES%EC%9D%98-%ED%83%84%EC%83%9D-%EB%B0%B0%EA%B2%BD

 https://www.dotnettricks.com/learn/stepbystep/Javascript/datatype



728x90
반응형
Comments