ECMA스크립트란❓❓
ECMA스크립트(ECMAScript, 또는 ES)란, Ecma International이 ECMA-262 기술 규격에 따라 정의하고 있는 표준화된 스크립트 프로그래밍 언어를 말한다. 자바스크립트를 표준화하기 위해 만들어졌다. 액션스크립트와 J스크립트 등 다른 구현체도 포함하고 있다. ECMA스크립트는 웹의 클라이언트 사이드 스크립트로 많이 사용되며 Node.js를 사용한 서버 응용 프로그램 및 서비스에도 점차 많이 쓰이고 있다.
역사
1996년 3월, 넷스케이프에서 넷스케이프 네비게이터 2.0을 출시하면서 자바스크립트를 지원하기 시작했다. 웹 페이지 동작을 향상시키는 언어로서 자바스크립트의 성공은, 마이크로소프트가 이와 "적당히" 호환되는 J스크립트를 개발하는 계기가 되었다. J스크립트는 1996년 8월, 인터넷 익스플로러 3.0에 포함되어 출시되었다.
넷스케이프는 표준화를 위해 자바스크립트 기술 규격을 Ecma 인터내셔널에 제출하였고, 이 규격에 대한 작업은 ECMA-262의 이름으로 1996년 11월부터 시작됐다. ECMA-262의 초판은 ECMA 일반 회의에서 1997년 6월 채택됐다.
ECMA스크립트는 ECMA-262에 의해 표준화된 언어의 이름이다. 자바스크립트와 J스크립트는 모두 ECMA스크립트와의 호환을 목표로 하면서, ECMA 규격에 포함되지 않는 확장 기능을 제공한다.
ECMA-262는 10개의 판이 출판되었다. 10판 표준에 대한 작업은 2019년 6월에 마무리됐다.
순서 출판일 변경점 1 1997년 6월 초판 2 1998년 6월 ISO/IEC 16262 국제 표준과 완전히 동일한 규격을 적용하기 위한 변경. 3 1999년 12월 강력한 정규 표현식, 향상된 문자열 처리, 새로운 제어문 , try/catch 예외 처리, 엄격한 오류 정의, 수치형 출력의 포매팅 등. 4 2004년 6월 버려짐 4번째 판은 언어에 얽힌 정치적 차이로 인해 버려졌다. 이 판을 작업 가운데 일부는 5번째 판을 이루는 기본이 되고 다른 일부는 ECMA스크립트의 기본을 이루고 있다. 5 2009년 12월 더 철저한 오류 검사를 제공하고 오류 경향이 있는 구조를 피하는 하부집합인 "strict mode"를 추가한다. 3번째 판의 규격에 있던 수많은 애매한 부분을 명확히 한다. 5.1 2011년 6월 ECMA스크립트 표준의 제 5.1판은 ISO/IEC 16262:2011 국제 표준 제3판과 함께 한다. 6 2015년 6월 ECMAScript 2015 (ES2015) 6판에는 클래스와 모듈 같은 복잡한 응용 프로그램을 작성하기 위한 새로운 문법이 추가되었다. 하지만 이러한 문법의 의미는 5판의 strict mode와 같은 방법으로 정의된다. 이 판은 "ECMAScript Harmony" 혹은 "ES6 Harmony" 등으로 불리기도 한다. 7 2016년 6월 ECMAScript 2016 (ES2016) 제곱연산자 추가, Array.prototype.includes 8 2017년 6월 ECMAScript 2017 (ES2017) 함수 표현식의 인자에서 trailing commas 허용, Object values/entries 메소드, async/await 등. 9 2018년 6월 ECMAScript 2018 (ES2018) Promise.finally, Async iteration, object rest/spread property 등. 10 2019년 6월 ECMAScript 2019 (ES2019) Object.fromEntries, flat, flatMap, Symbol.description, optional catch 등.
2004년 6월에 Ecma 인터내셔널은 E4X(XML을 위한 ECMA스크립트)로 알려진 ECMA스크립트의 확장을 정의하는 ECMA-357을 출판했으나 2015년에 표준에서 제외됐다.
ES5와 ES6에 대한 차이는❓❓
ES5와 ES6의 대표적인 차이점으로 아래 항목들을 들 수 있다.
템플릿 리터럴
화살표 함수
this
변수선언
모듈
클래스
템플릿 리터럴
ES6부터 새롭게 등장한 템플릿 리터럴. 덕분에 문자열 표현이 훨씬 간단해졌다.
템플릿 리터럴이란 작은 따옴표나 큰 따옴표 대신 백틱(`)으로 문자열을 감싸 표현하는 기능을 말한다.
템플릿 리터럴을 사용하면 플레이스 홀더(${variable})를 사용하여 백틱 내부에 문자열과 함께 표현식을 넣을 수 있다.
ES5
var name = "현진"; var age = 25; console.log("저의 이름은 " + name + "이고, 나이는 " + age + "살 입니다.");
ES6
var name = "현진"; var age = 25; console.log(`저의 이름은 ${name}이고, 나이는 ${age}살 입니다.`);
화살표 함수
ES6부터 새롭게 등장한 화살표 함수로 함수 선언법이 좀 더 간단해졌다.ES5
function str(arg1, arg2) { console.log("용민"); } // 생성자 함수(많이 사용하지 않음) var str = new Function("arg1", "arg2", "console.log('용민')");
함수 리터럴(익명 함수를 만들 때 사용)
var str = function(arg1, arg2) { console.log("용민"); };
참고💨💨
여기서 익명 함수란 말 그대로 이름이 없는 함수를 뜻한다.ex) var bar = function (a, b) {...};
반대로 기명 함수는 이름이 있는 함수이다.
ex) var bar = function funcName(a, b) {...}
ES6
var str = (arg1, arg2) => { console.log("용민"); }; var str = arg1 => console.log(arg1);
화살표 함수에 인자(argument)가 하나밖에 없다면 괄호를 생략할 수 있다. 또한 한줄로 표현이 가능하다면 위와 같이 중괄호({})를 생략할 수 있다.
var str = func => ({ id: "31" });
화살표 함수가 객체를 반환한다면 위와같이 표현해줄 수 있다.
this의 다른 동작
ES5
ES5같은 경우 객체 내에 있는 메소드를 실행 시 this는 메소드가 선언된 해당 객체를 가리킨다.
하지만 객체 안에서 선언된 함수의 this는 해당 객체가 아닌 window를 바라보고 있기 때문에 함수 안에서 this.name, this.age 를 하여도 아무 값이 나오지 않는다.
이러한 경우 해결방안으로 innerInfo.call(this) 를 통해 this 를 바인딩 시켜주거나 this를 해당 변수에 담아서 var self = this 와 같은 방식으로 접근하면 사용하면 된다.var thisTest = { name : "김현진", age : 25, info : function() { console.log(this) console.log(this.name , this.age) function innerInfo() { console.log(this) return this.name + ":" + this.age } return innerInfo() } } // 실행결과 // {name: "김현진", age: 25, info: ƒ} // 김현진 25 // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …} // ":undefined"
ES6
ES6에서의 this 는 자신을 둘러싸고 있는 this를 바라보기 때문에 따로 바인딩이나 변수에 담을 필요 없다.
let thisTest = { name : "김현진", age : 25, info() { console.log(this) console.log(this.name , this.age) innerInfo = () => { console.log(this) return this.name + ":" + this.age } return innerInfo() } } // 실행결과 // {name: "김현진", age: 25, info: ƒ} // 김현진 25 // {name: "김현진", age: 25, info: ƒ} // "김현진:25"
생성자 함수의 인스턴스의 경우, this는 인스턴스를 가리킨다.
function Obj(value) { this.value = value; } var obj = new Obj(0); console.log(obj.value); // 0
화살표 함수를 쓰면 함수가 선언된 스코프에 자동 바인딩이 된다.
var obj = { value: 10, // 메소드 호출 show: function () { console.log(this.value); // 10 // 함수 호출 function show_01 () { console.log(this.value); // undefined } show_01(); // 화살표 함수 function show_02 = () => { console.log(this.value); // 10 } show_02(); } } obj.show();
변수 선언
ES5
ES5에선 var 밖에 존재하지 않았다. var 는 변수를 선언할 때 사용되는 키워드로,
재할당과 재선언에 굉장히 자유롭다.var x = 10; x = 15; console.log(x); //15 var x = 12; console.log(x); //12
ES6
ES6부터 let, const가 추가되었다.
let은 한번 선언된 변수에 동일한 이름으로 선언할 수 없다.
하지만, 값은 재할당 할 수 있다.copy javascript let x = 10; x = 15; console.log(x); //15 let x = 12; // Identifier 'x' has already been declared
const는 한번 초기화된 변수에 재할당/재선언할 수 없다.
const x = 10; console.log(x); // 10; x = 15; // TypeError: Assignment to constant variable.
그리고, let, const는 블록 스코프 또는 Function 스코프 내부에 선언되면 해당 스코프 밖에서 안에 있는 변수를 참조할 수 없다.
쉽게 설명하자면, 중괄호로 묶인 부분 내부에 선언된 let, const를 중괄호 외부에서 참조할 수 없다는 것이다.if (true) { var i = 0; } console.log(i); // 0 if (true) { let j = 10; } console.log(j); // ReferenceError if (true) { const k = 100; } console.log(k); // ReferenceError
밖에서 안에 있는 const, let은 참조할 수는 있다.
const i = 5; if (ture) { console.log(i); // 5 }
var는 Function 스코프는 내부에 선언된 var를 외부에서 참조할 수 없지만
블록 스코프에선 내부에 선언되어 있어도 외부에서 참조 가능하다.function f() { var v = 5; console.log(v); // 5 } console.log(v); // ReferenceError: v is not defined if (true) { var i = 0; } console.log(i); // 0
정리하자면 다음과 같다.
선언방식 재 선언 재 할당 Block scope Function scope var O O 외부에서 내부 참조 가능 let X O 외부에서 내부 참조 불가 const X X 외부에서 내부 참조 불가