-
[JS] 자바스크립트 프레임워크 내부 파헤치기 4가지Javascript 2021. 1. 3. 20:51
JavaScript는 이제 많은 라이브러리와 프레임워크가 파생된 매우 인기있는 프로그래밍 언어입니다.
하지만 상위 생태계가 어떻게 진화하든 바닐라 자바스크립트 없이는 불가능합니다.
여기에서는 프로그래머의 바닐라 JavaScript 기술을 테스트하기 위해 4개의 JavaScript 인터뷰 질문을 선택했습니다.
1. Array.prototype.map 구현
Array.prototype.map 메서드를 직접 구현하는 방법은 무엇입니까?
lodash를 참조하면 다음과같은 맵 함수를 작성할 수 있습니다.
function map(array, iteratee) { let index = -1 const length = array == null ? 0 : array.length const result = new Array(length) while (++index < length) { result[index] = iteratee(array[index], index, array) } return result }
2. Object.defineProperty and Proxy
obj.a를 연속으로 세 번 출력하면 세 가지 결과가 나옵니다.
얼마나 놀라운 일입니까!
let obj = { get a(){ console.log('triggle get a() method') console.log('you can do anything as you want') return 1 }, set a(value){ console.log('triggle set a() method') console.log('you can do anything as you want') console.log(`you are trying to assign ${value} to obj.a`) } }
액세스 속성은 강력한 메타 프로그래밍 기능을 제공하므로 다음과 같은 방식으로 요구 사항을 충족 할 수 있습니다.
let obj = { _initValue: 0, get a() { this._initValue++; return this._initValue } } console.log(obj.a, obj.a, obj.a)
두 번째 방법은 Object.defineProperty를 사용하는 것입니다.
이 방법은 액세스 속성을 직접 선언하는 대신 Object.defineProperty를 통해 액세스 속성을 구성한다는 점을 제외하면 속성에 액세스하는데 사용한 것과 동일한 방식으로 작동합니다.
let obj = {} Object.defineProperty(obj, 'a', { get: (function(){ let initValue = 0; return function(){ initValue++; return initValue } })() }) console.log(obj.a, obj.a, obj.a)
여기에있는 get 메소드에서 우리는 우리가 사용해야하는 initValue 변수가 클로저에 숨겨져 있고 다른 범위를 침범하지 않도록 클로저를 사용합니다.
세 번째 방법은 프록시를 사용하는 것입니다.
프록시를 사용하면 객체 속성에 대한 액세스를 가로 챌 수 있습니다.
Proxy를 사용하여 obj.a에 대한 액세스를 가로 챈 다음 차례로 1, 2, 3을 반환하는 한, 요구 사항을 완료 할 수 있습니다.
let initValue = 0; let obj = new Proxy({}, { get: function(item, property, itemProxy){ if(property === 'a'){ initValue++; return initValue } return item[property] } }) console.log(obj.a, obj.a, obj.a)
이 질문을 이해하는 것이 왜 중요한가요?
Object.defineProperty 및 Proxy가 강력한 메타 프로그래밍 기능을 제공했기 때문에 우리는 개체를 적절하게 수정하여 특별한 작업을 수행 할 수 있습니다.
잘 알려진 프런트엔드 프레임워크인 Vue에서 핵심 메커니즘 중 하나는 데이터의 양방향 바인딩입니다.
Vue2.0에서 Vue는 Object.defineProperty를 사용하여이 메커니즘을 구현했습니다.
Vue3.0에서 Proxy는 이 메커니즘을 수행하는데 사용됩니다.
프레임워크 이전에 알아야할 필요성을 느끼시나요?
이것을 마스터하지 않으면 Vue와 같은 프레임 워크가 어떻게 작동하는지 정말 이해할 수 없습니다.
이 원칙을 숙달하면 Vue를 배우는 데 절반의 노력으로 두 배의 결과를 얻을 수 있습니다.
3. Scope and Closure
이 코드의 실행 결과는 무엇일까요?
function foo(a,b) { console.log(b) return { bar:function(c){ return foo(c,a); } }; } let res = foo(0); res.bar(1); res.bar(2); res.bar(3);
먼저 위의 코드에 몇 개의 함수가 있는지 확인해 봅시다.
위 코드에서 키워드 function이 두 곳에서 사용되는 것을 볼 수 있으므로 위 코드에는 두 개의 함수가 있습니다.
즉, 첫 번째 줄 function foo (a, b) {및 네 번째 줄 foo : function (c) { .
그리고 이 두 기능은 같은 이름을 가지고 있습니다.
그리고, 5 행에서 foo (c, a)가 호출하는 함수는 무엇입니까?
확실하지 않은 경우 더 간단한 예를 살펴 보겠습니다.
var obj={ fn:function (){ console.log(fn); } }; obj.fn()
이 코드를 실행하면 예외가 발생합니까? 대답은 '예'입니다.
이는 obj.fn () 메서드의 상위 범위가 전역이고 obj 내부의 fn 메서드에 액세스 할 수 없기 때문입니다.
foo(c,a) 가 호출되는 과정을 다이어그램으로 보면 다음과 같습니다.
사실 위의 질문은 다른 방식으로 변경 될 수 있습니다. 예를 들어 다음과 같이 변경할 수 있습니다.
function foo(a,b) { console.log(b) return { foo:function(c){ return foo(c,a); } }; } foo(0).foo(1).foo(2).foo(3);
위 코드의 경우에는 새로운 스코프를 생성하지 않고 내부에 스코프를 형성하므로 다른 답을 출력합니다.
4. Compose
function compose (middleware) { // some code }
let middleware = [] middleware.push((next) => { console.log(1) next() console.log(1.1) }) middleware.push((next) => { console.log(2) next() console.log(2.1) }) middleware.push(() => { console.log(3) }) let fn = compose(middleware) fn()
fn을 실행하려고하면 미들웨어의 함수를 호출하고 다음 함수를 각 작은 함수에 매개 변수로 전달합니다.
위 코드를 실행하면 다음과 같은 결과가 나옵니다.
1 2 3 2.1 1.1
compose 함수를 구성하면 다음과 같습니다.
function compose(middleware){ return async function(){ await dispatch(0) function async dispatch(i){ const fn = middleware[i] if (!fn) return null await fn(function next(){ dispatch(i + 1) }) } } }
실제로 위의 compose 함수는 잘 알려진 노드 프레임 워크 koa의 핵심 메커니즘입니다.
결국, 자바스크립트 생태계에는 너무나 많은 라이브러리와 프레임워크가 있어서 아무도 모두 마스터 할 수 없습니다.
그러나 모든 라이브러리와 프레임워크의 기초이기 때문에 이러한 중요한 바닐라 자바스크립트 트릭을 알고 있기를 바랍니다.
'Javascript' 카테고리의 다른 글
가속 animation javascript (0) 2021.02.02 [JS] Snowpack3 - ESM의 시대가 곧 도래합니다. (0) 2021.01.23 ES2020 7가지 새로운 팁 (0) 2020.06.29 [javscript] 12가지 Array 팁 (0) 2020.06.28 Constructor vs Literal (0) 2020.06.22