@ 궁금한 이유
리액트든 노드든 뭘 JS 에 대한 강력한 이해가 필요하기 때문에 많이 알고 있다고 생각했지만, 순각적으로 막히는 경우가 많다는 것을 리액트 공부하면서 많이 느낀다.
@ 공부
## moder JavaScript
In the old days, you could just include a <script> tag in the header of your webpage, and your JavaScript would run as intended. These days, we preprocess our JavaScript in order to access experimental features and language extensions like JSX
> 전에 사용한 JS는 나중에 돌아 가도록 했다면 이제는 전처리를 위한 작업을 위해서 JS가 돌아 간다.
## babel
Babel is the main tool used to preprocess JavaScript. Babel is a highly configurable compiler that lets you use experimental features and extensions, compiling down into older versions of JavaScript that can be supported on a wider range of platforms. Of course, if a native platform doesn't support an ES6 feature like Promise(), Babel won't fully be able to help -- but it can in many cases polyfill missing APIs to provide this functionality.
> 버전에 안맞는 문법 같은 경우는 babel 이 도와준다.
## ES2015
For the most part, all ES2015 features are now available in modern JavaScript engines. Using Babel, however, gives us access to newer features which aren't yet, while ensuring our JavaScript runs on even more platforms. React Native uses Babel to enable ES2015 (and newer) features and ensure cross-platform consistency, so your JavaScript can run on Android, iOS, Windows, and other platforms
> Babel 덕분에 어느 곳에 든지 JS 를 구동할 수 있게 되었다.
## 선언 방법 (Block Scoped Declarations)
var 변수를 선언 추가로 동시에 값을 초기화
> var x = 42; 이 구문은 지역 및 전역 변수를 선언하는데 모두 사용
let 블록 범위 지역 변수를 선언, 추가로 동시에 값을 초기화
> 간단하게 값을 할당,
const 블록 범위 읽기 전용 상수를 선언
# 변수
- JS 식별자는 문자, 밑줄, 혹은 달러 기호로 시작하거나, 숫자도 존재한다.
- JS는 대소문자를 구분한다.
# undefined , null, NaN
var input;
if(input === undefined){
doThis();
}else{
doThat();
}
그럼 undefined vs null 에 대해서 생각해 보면
null : 값은 값이지만, 값으로써 의미없는 특별한 값이 등록되어 있는 것
> typeof(null) > Object 로 나오게 된다.
undefined : 등록이 되어 있지 않기 때문에 초기화도 정의되지도 않은 것
NaN : Not-A-Number ( 숫자가 아님 ) 을 이야기 한다.
// Number 변수 초기화
var data1 = 0;
// String 변수 초기화
var data2 = "";
// Boolean 변수 초기화
var data3 = false;
// Object 변수 초기화
var data4 = null;
## 변수 호이스팅
ECMAScript 2015의 let (const)는 변수를 블록의 상단으로 올리지 않습니다.
변수가 선언되기 전에 블록 안에서 변수를 참조하게 되면 ReferenceError를 발생시키게 됩니다.
변수는 블록 시작부터 선언이 처리될 때까지 'temporal dead zone'에 위치하게 됩니다.
## 함수 호이스팅
함수에서는 단지 함수 선언만 상단으로 끌어올려집니다. 함수 표현식은 그렇지 않습니다.
## 상수
const 키워드로 읽기 전용 상수를 만들수 있다.
> 상수는 같은 범위에 있는 함수나 변수와 동일한 이름으로 선언할 수 없습니다.
// 오류가 발생합니다
function f() {};
const f = 5;
// 역시 오류가 발생합니다
function f() {
const g = 5;
var g;
//statements
}
단 상수에 할당된 객체의 속성과 배열의 내용도 보호되지 않습니다.
const MY_OBJECT = {'key': 'value'};
MY_OBJECT.key = 'otherValue';
//////////////////
const MY_ARRAY = ['HTML','CSS'];
MY_ARRAY.push('JAVASCRIPT');
console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT'];
두개 모두 문제 없다.
## 데이터 형
총 7가지
- Boolean > true,false
- null > NULL(x), Null (x)
- undefined
- Number
- String
- Symbol
- Object
# 자료형 변환
JS는 동적 형지형(정형) 언어 입니다. 그래서 선언할 때 데이터 형을 지정할 필요가 없음을 의미한다.
> 그냥 "+" 를 사용해서 변환도 가능
- "1"+2 // 3
- "안녕하세요" +3 // 안녕하세요 3
- parseInt() : 오직 정수만 반환, 그리고 진버 매개변수를 포함해야 한다.
- parseFloat()
문자열을 숫자로 변환
## 리터럴
값을 나타내기 위해서 리터럴 사용.
# 배열 리터럴
일종의 객체 이니셜라이저입니다.
#객체 리터럴
class 컴포넌트
React 에서 컴포넌트를 정의 할 때는 보통 EcmaScipt 6 에 도입된 class 문법을 사용합니다. 컴포넌트에서 라이프사이클 API 를 사용해야 하거나, state 를 사용하는 경우에는 꼭 이렇게 정의를 해야하죠.
- 라이프사이클 API -
constructor > 브라우저 나타나기 전 컴포넌트 생성자 함수, 컴포넌트가 새로 만들어질 때마다 이 함수가 호출됩니다.
componentWilMount > 화면 나가기 직전에 호출되는 API, ( 서버사이드에서도 호출되는 거라 딱히 신경 ㄴ)
componetnDidMount > 화면에 나타나게 됐을 때 호출 되는 API, DOM을 사용해야 하는 외부 라이브러리 연동하거나, 해당 컴포넌트에서 필요로하는 데이터를 요청하기 위해 axios,fetch등을 통하여 ajax 요청을 하거나, DOM의 속성을 읽거나 직접 변경하는 직업을 진행
- static -
propTypes,
defaultProps
https://ko.reactjs.org/docs/typechecking-with-proptypes.html
함수형 컴포넌트
만약에 여러분이 만들 컴포넌트가 라이프사이클 API 도 사용하지 않고, state 도 사용하지 않고, 그냥 props 만 전달해주면 뷰를 렌더링만 해주는 역할이라면 함수형 컴포넌트 형식으로 컴포넌트를 정의 할 수 있습니다.
## Arrow Functions
The fat arrow => is used to define anonymous functions. 그냥 function 하고 두가지 다른 점이 있습니다.
1. this 에 대한 바인딩문제
자바와 달리 자바스크립트의 경우 Java와 같이 this에 바인딩되는 객체는 한가지가 아니라 해당 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라진다. 다시 말하면 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.
- 함수 호출
- 메소드 호출
- 생성자 함수 호출
- apply/call/bind 호출
함수의 상위 스코프를 결정하는 방식인 렉시컬 스코프(Lexical scope)는 함수를 선언할 때 결정된다. this 바인딩과 혼동하지 않도록 주의하기 바란다.
function Prefixer(prefix) {
this.prefix = prefix;
}
Prefixer.prototype.prefixArray = function (arr) {
// (A)
return arr.map(function (x) {
return this.prefix + ' ' + x; // (B)
});
};
var pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']));
(A) 지점에서의 this는 생성자 함수 Prefixer가 생성한 객체, 즉 생성자 함수의 인스턴스(위 예제의 경우 pre)이다.
(B) 지점에서 사용한 this는 아마도 생성자 함수 Prefixer가 생성한 객체(위 예제의 경우 pre)일 것으로 기대하였겠지만, 이곳에서 this는 전역 객체 window를 가리킨다. 이는 생성자 함수와 객체의 메소드를 제외한 모든 함수(내부 함수, 콜백 함수 포함) 내부의 this는 전역 객체를 가리키기 때문이다.
// Solution 1: that = this
Prefixer.prototype.prefixArray = function (arr) {
var that = this; // this: Prefixer 생성자 함수의 인스턴스
return arr.map(function (x) {
return that.prefix + ' ' + x;
});
};
// Solution 2: map(func, this)
Prefixer.prototype.prefixArray = function (arr) {
return arr.map(function (x) {
return this.prefix + ' ' + x;
}, this); // this: Prefixer 생성자 함수의 인스턴스
};
// Solution 3: bind(this)
Prefixer.prototype.prefixArray = function (arr) {
return arr.map(function (x) {
return this.prefix + ' ' + x;
}.bind(this)); // this: Prefixer 생성자 함수의 인스턴스
};
화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정된다. 동적으로 결정되는 일반 함수와는 달리 화살표 함수의 this 언제나 상위 스코프의 this를 가리킨다. 이를 Lexical this라 한다. 화살표 함수는 앞서 살펴본 Solution 3의 Syntactic sugar이다
# 스코프
자바스크립트에서 스코프란 어떤 변수들에 접근할 수 있는지를 정의합니다. 스코프엔 두 가지 종류가 있는데요, 전역 스코프(global scope)와 지역 스코프(local scope)가 있죠
- 전역 스코프(Global Scope)
변수가 함수 바깥이나 중괄호 ({}) 바깥에 선언되었다면, 전역 스코프에 정의된다고 합니다
Node.js에서는 전역 스코프를 다르게 정의하지만,
- 지역 스코프(Local Scope)
여러분이 중괄호({}) 내부에서 const 또는 let으로 변수를 선언하면, 함수 내부에서 변수를 선언하면, 그 변수는 선언한 변수 내부에서만 접근할 수 있습니다
2. 화살표 함수의 argument
@ 참고
https://medium.com/front-end-weekly/understanding-static-in-javascript-10782149993
'FE > JS' 카테고리의 다른 글
setTimeOut (0) | 2021.08.17 |
---|---|
[Js] 무한 스크롤 (0) | 2021.07.31 |
[ JavaScript ] 내장함수 (0) | 2019.09.25 |
[ JS ] 비동기 ( axios , promise, async ,,) (0) | 2019.09.05 |
JS - var,let,const (0) | 2019.07.11 |
댓글