[프런트 엔드 사전] Vue 소스 코드 학습에 필요한 지식 보유

머리말

현재 Vue 용 고급 콘텐츠를 작성하고 있습니다. 이 과정에서 어떤 사람들은 Vue 소스 코드를 읽으려면 어떤 준비가 필요한지 물었습니다. 그래서이 계획 밖에있는 기사가 있습니다.

Vue 소스 코드를 배우고 자 할 때는 탄탄한 JavaScript 기반이 필요하며 다음 목록은 대표적인 지식 포인트 중 일부일뿐입니다. 자바 스크립트 기반이 없다면 Vue 소스 코드를 서두르지 않는 것이 좋습니다. 그래서 쉽게 포기할 수 있습니다.

다음 7 가지 포인트부터 시작하겠습니다.

  1. 흐름 기본 구문

  2. 게시 / 구독 모델

  3. Object.defineProperty

  4. ES6 + 구문

  5. 프로토 타입 체인, 클로저

  6. 기능 카레

  7. 이벤트 루프

[프런트 엔드 사전] Vue 소스 코드 학습에 필요한 지식 보유

필요한 지식 보유

이 기사의 각 요점은 구체적으로 설명하지 않고 여기에서 몇 가지 지식 요점을 요약하겠습니다. 각 세부 사항은 여전히 ​​학습하는 데 시간을 투자해야합니다.

흐름 기본 구문

Vue, Vuex 등의 소스 코드를 본 사람은 누구나 Flow 정적 유형 검사 도구를 사용한다는 것을 알고 있습니다.

JavaScript가 약한 유형의 언어라는 것을 알고 있으므로 코드를 작성할 때 예기치 않은 문제가 발생하기 쉽습니다. 이 문제 때문에 정적 유형 검사 도구 인 Flow가 등장했습니다.

이 도구는 JavaScript가 약한 유형의 언어라는 상황을 변경할 수 있으며 유형 제한을 추가하여 코드 품질을 향상시킬 수 있습니다.

// 未使用 Flow 限制

function sum(a, b) {

  return a + b;

}

// 使用 Flow 限制  a b 都是 number 类型。

function sum(a: number, b:number) {

  return a + b;

}

기본 감지 유형

Flow는 다음과 같은 기본 데이터 유형을 지원합니다.

boolean

number

string

null

void( 对应 undefined )

변수를 정의 할 때 다음을 사용하여 주요 위치에서 유형을 선언하십시오.

let str:string = 'str';

// 重新赋值

str = 3  // 报错

복잡한 유형 감지

Flow는 다음을 포함한 복잡한 유형 감지를 지원합니다.

Object

Array

Function

自定义的 Class

flow.js를 직접 사용하면 JavaScript를 브라우저 측에서 실행할 수 없습니다. babel 플러그인을 사용해야합니다. babel-preset-flow-vue 플러그인은 vue 소스 코드에서 사용되며 babelrc에서 구성됩니다.

자세한 흐름 구문은 다음 정보에서 볼 수 있습니다.

여기에는 두 가지 재료가 권장됩니다.

  1. 공식 문서 : https://flow.org/en/

  2. Flow 시작하기 : https://zhuanlan.zhihu.com/p/26204569

게시 / 구독 모델

Vue는 내부적으로 양방향 바인딩 메커니즘을 구현하므로 이전과 같이 DOM을 조작 할 필요가 없습니다.

실제로 Vue의 양방향 바인딩 메커니즘은 게시 / 구독 모델과 ​​결합 된 데이터 하이재킹을 사용하여 Object.defineProperty ()를 통해 각 속성의 setter 및 getter를 하이재킹하고, 데이터가 변경 될 때 구독자에게 메시지를 게시하고, 해당 리스너 콜백을 트리거합니다.

어떤 사람들은 옵저버 모델과 발행 / 구독 모델을 혼동하는 것을 발견했습니다. 사실 구독 모델에는 구독 이벤트의 통합 관리를위한 디스패치 센터가 있습니다. 관찰자 모드는 마음대로 이벤트를 등록하고 호출 할 수 있습니다.

관찰자 모델과 게시 / 구독 모델을 설명하기 위해 일반적인 순서도를 그렸습니다. 다음과 같이 :
[프런트 엔드 사전] Vue 소스 코드 학습에 필요한 지식 보유

이에 대해서는 다음 기사에서 자세히 설명하겠습니다. 먼저 개념을 소개합니다. 관심이 있으시면 직접 정보를 찾거나 내 기사가 게시 될 때까지 기다리십시오.

사실, 우리는이 패턴에 대해 잘 알고 있지만 여러분 스스로 알아 차리지 못했을 수도 있습니다.

let div = document.getElementById('#div');

div.addEventListener('click', () => {

    console.log("div 被点击了一下")

})

위의 이벤트 바인딩 실행 과정을 생각할 수 있습니다. 공명이 있어야합니다.

기능 카레

양방향 데이터 바인딩의 기초 : Object.defineProperty ()

하나, 데이터 속성

데이터 속성에는 데이터 값의 위치가 포함됩니다. 이 위치는 값을 읽고 쓸 수 있습니다. 데이터 속성에는 동작을 설명하는 네 가지 특성이 있습니다.
[프런트 엔드 사전] Vue 소스 코드 학습에 필요한 지식 보유
위의 네 가지 기본 데이터 속성을 수정하려면 ECMAScript의 Object.defineProperty () 메서드를 사용해야합니다.

이 메서드에는 속성이있는 개체, 속성 이름 및 설명자 개체의 세 가지 매개 변수가 포함됩니다. 설명자 개체의 속성은 위의 4 개 속성에 있어야합니다.

var person = {

  name: '',

};

// 不能修改属性的值

Object.defineProperty(person, "name",{

    writable: false,

    value: "小生方勤"

});

console.log(person.name);   // "小生方勤"

person.name = "方勤";

console.log(person.name);  // "小生方勤"

둘째, 접근 자 속성

접근 자 속성은 데이터 값을 포함하지 않으며 getter 및 setter 함수 쌍을 포함합니다 (필수 아님). 접근 자 속성의 값을 읽고 쓸 때 해당 getter 및 setter 함수가 호출되고 vue는 필요한 작업을 getter 및 setter 함수에 추가합니다.

[value or writable]은 [get or set]과 공존 할 수 없습니다.

접근 자 속성에는 다음과 같은 4 가지 특성이 있습니다.
[프런트 엔드 사전] Vue 소스 코드 학습에 필요한 지식 보유
예를 들어 보겠습니다.

var person = {

    _name : "小生方勤"

};

Object.defineProperty(person, "name", {

    //注意 person 多定义了一个 name 属性

    set: function(value){

        this._name = "来自 setter : " + value;  

    },

    get: function(){

        return "来自 getter : " + this._name; 

    }

});

console.log( person.name );   // 来自 getter : 小生方勤

person.name = "XSFQ";        

console.log( person._name );  // 来自 setter : XSFQ

console.log( person.name );   // 来自 getter : 来自 setter : XSFQ

이전에 Object.defineProperty () 메소드를 알지 못 하셨다면 "JavaScript Advanced Programming"의 139-144 페이지를 읽어 보시기 바랍니다.

Object.create (null)에 대한 추가 설명

소스 코드의 모든 곳에 this.set = Object.create (null)과 같은 값을 할당 할 수 있습니다. 왜 이러나요? 이러한 방식으로 작성하는 장점은 프로토 타입 체인의 속성을 고려할 필요가 없으며 실제로 순수한 객체를 만들 수 있다는 것입니다.

우선 Object.create는 객체를 상속받는 것으로 이해 될 수 있으며 ES5의 기능이며 이전 브라우저와 호환되어야합니다. 기본 코드는 다음과 같습니다.

if (!Object.create) {

    Object.create = function (o) {

        function F() {}     // 定义了一个隐式的构造函数

        F.prototype = o;

        return new F();     // 其实还是通过new来实现的

    };

}

ES6 + 구문

사실 이것은 당신이 기본적으로 알아야 할 것입니다. 그러나 누군가가 전에 몇 가지 관련 질문을했기 때문에 그것에 대해 조금 이야기하겠습니다.
exportdefault와 export의 차이점

  1. 파일 또는 모듈에 여러 내보내기가있을 수 있지만 하나의 내보내기 기본값 만 있습니다.

  2. 내보내기를 통해 내보내고 가져올 때 {}을 추가하지만 exportdefault는 필요하지 않습니다.

    1. 내보내기

    //a.js

    내보내기 const str = "Xiaosheng Fangqin";

    //b.js

    import {str} from'a '; // 가져올 때 중괄호가 필요합니다.

    2. 기본 내보내기

    //a.js

    const str = "Xiaosheng Fang Qin";

    기본 str 내보내기;

    //b.js

    import str from'a '; // 가져올 때 중괄호가 필요하지 않습니다.

exportdefaultconsta=1; 这样写是会报错的哟。

화살표 기능

이것은 취했습니다.

  1. 화살표 함수에서이 방향, 즉 함수가 정의 된 방향은 고정되어 있습니다.

  2. 일반 함수에서 this는 그것이 가리키는 때, 즉 함수가 사용되는 지점에서 변경됩니다.

클래스 상속

클래스는 extends 키워드를 통해 상속 될 수 있는데, 프로토 타입 체인을 수정하여 ES5의 상속보다 훨씬 명확하고 편리합니다.

class staff { 

  constructor(){

    this.company = "ABC";    

    this.test = [1,2,3];

  }

  companyName(){

    return this.company; 

  }

}

class employee extends staff {

  constructor(name,profession){

    super();

    this.employeeName = name;

    this.profession = profession;

  }

}

// 将父类原型指向子类

let instanceOne = new employee("Andy", "A");

let instanceTwo = new employee("Rose", "B");

instanceOne.test.push(4);

// 测试 

console.log(instanceTwo.test);    // [1,2,3]

console.log(instanceOne.companyName()); // ABC

// 通过 Object.getPrototypeOf() 方法可以用来从子类上获取父类

console.log(Object.getPrototypeOf(employee) === staff)

// 通过 hasOwnProperty() 方法来确定自身属性与其原型属性

console.log(instanceOne.hasOwnProperty('test'))          // true

// 通过 isPrototypeOf() 方法来确定原型和实例的关系

console.log(staff.prototype.isPrototypeOf(instanceOne));    // true

부모 클래스의 생성자를 나타내는 super 키워드는 부모 클래스의 this 개체를 만드는 데 사용됩니다.

  1. 서브 클래스는 생성자 메서드에서 super 메서드를 호출해야합니다. 그렇지 않으면 인스턴스를 만들 때 오류가보고됩니다. 이는 하위 클래스에 자체이 개체가 없지만 부모 클래스의이 개체를 상속 한 다음 처리하기 때문입니다.

  2. 이 키워드는 super를 호출 한 후에 만 ​​사용할 수 있습니다. 그렇지 않으면 오류가보고됩니다. 이는 서브 클래스 인스턴스의 구성이 수퍼 클래스 인스턴스 처리를 기반으로하고 수퍼 메소드 만이 수퍼 클래스 인스턴스를 리턴 할 수 있기 때문입니다.
`super` 虽然代表了父类 `A` 的构造函数,但是返回的是子类 `B` 的实例,即` super` 内部的 `this ` 指的是 `B`,因此 `super()` 在这里相当于 A.prototype.constructor.call(this)

ES5와 ES6 구현 상속의 차이점

ES5 상속의 본질은 먼저 하위 클래스의 this 인스턴스 객체를 만든 다음 부모 클래스의 메서드를 여기에 추가하는 것입니다 (Parent.apply (this)).
ES6의 상속 메커니즘은 완전히 다릅니다. 본질은 먼저 부모 클래스의 this 인스턴스 객체를 만든 다음 (따라서 super () 메서드를 먼저 호출해야 함) 하위 클래스의 생성자를 사용하여이를 수정하는 것입니다.

대리

최신 개발 사항을 알고있는 사람들은 Vue의 다음 버전에서는 데이터 하이재킹을 완료하기 위해 Object.defineProperty 대신 프록시가 사용된다는 것을 알 것입니다.

You Da는이 새로운 솔루션이 메모리 사용량을 절반으로 줄이면서 초기화 속도를 두 배로 높일 것이라고 말했습니다.

프록시 개체의 사용 :

var proxy = new Proxy(target, handler);

new Proxy ()는 Proxy 인스턴스를 생성합니다. target 매개 변수는 가로 챌 대상 개체를 나타내며, handler 매개 변수는 가로 채기 동작을 사용자 지정하는 개체이기도합니다.

var proxy = new Proxy({}, {

    get: function(obj, prop) {

        console.log('get 操作')

        return obj[prop];

    },

    set: function(obj, prop, value) {

        console.log('set 操作')

        obj[prop] = value;

    }

});

proxy.num = 2; // 设置 set 操作

console.log(proxy.num); // 设置 get 操作 // 2

가져 오기 및 설정 외에도 프록시는 최대 13 개의 작업을 가로 챌 수 있습니다.

注意,proxy 的最大问题在于浏览器支持度不够,IE 完全不兼容。

ES6를 모르는 경우 다음 자습서를 권장합니다.

Ruan Yifeng ECMAScript 소개 6 : http://es6.ruanyifeng.com/

프로토 타입 체인, 클로저

프로토 타입 체인

이전에 프로토 타입 체인을 설명하기 위해 일부러 기사를 썼기 때문에 여기서는 설명하지 않겠습니다.

프로토 타입 체인 : https://juejin.im/post/5c335940f265da610e804097

폐쇄

여기에서는 먼저 Vue 소스 코드에 한 번의 함수를 넣었습니다. 이것은 클로저 호출입니다-반환 값으로 함수 :

/**

 * Ensure a function is called only once.

 */

export function once (fn: Function): Function {

  let called = false

  return function () {

    if (!called) {

      called = true

      fn.apply(this, arguments)

    }

  }

}

이 함수의 목적은 함수가 한 번만 호출되도록하는 것입니다.

한 번만 호출되는 이유 함수 호출이 완료된 후에는 해당 실행 컨텍스트가 파괴되지 않으므로 called 값이 그대로 유지됩니다.

클로저가 정확히 무엇입니까? "JavaScript 고급 프로그래밍"에 대한 설명은 다음과 같습니다.

클로저는 다른 함수의 범위에있는 변수에 액세스 할 수있는 함수입니다. 클로저를 만드는 일반적인 방법은 다른 함수 안에 함수를 만드는 것입니다.

简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。

두 개의 코드를 제공합니다. 결과를 알고 있다면 클로저에 대해 알고 있습니다.

// 第一段

var num = 20;

function fun(){

    var num = 10;

    return function con(){

        console.log( this.num )

    }

}

var funOne = fun();

funOne();  // 20

// 第二段

var num = 20;

function fun(){

    var num = 10;

    return function con(){

        console.log( num )

    }

}

var funOne = fun();

funOne(); // 10

기능 카레

所谓"柯里化",就是把一个多参数的函数,转化为单参数函数。

이전에 접했던 인터뷰 질문에 대해 이야기하겠습니다.

如何使 add(2)(3)(4)() 输出 9

인터뷰 당시에도 카레의 개념을 몰라 대답하지 않았습니다. 나중에 나는 이것이 함수 커링으로 해결할 수 있다는 것을 배웠습니다.

function add(num){

    var sum=0;

    sum= sum+num;

    return function tempFun(numB){

        if(arguments.length===0){

            return sum;

        }else{

            sum= sum+ numB;

            return tempFun;

        }

    }

}

그렇다면 이것이 Vue와 어떤 관련이 있습니까? 물론 관련이 있습니다.

이런 판단을 자주 쓰는가?

if( A ){

 // code

}else if( B ){

 // code

}

이 글쓰기 방식에 문제는 없지만 같은 판단이 반복 될 때. 이것은 약간 지능적이지 않습니다. 이때 기능 커링이 유용 할 수 있습니다.

Vue는 다른 플랫폼에서 실행될 수 있기 때문에 위의 판단도 존재할 것입니다. 여기서는 카레의 특성을 살려 재사용을 위해 createPatchFunction 메서드를 통해 일부 매개 변수를 미리 저장합니다.

// 这样不用每次调用 patch 的时候都传递 nodeOps 和 modules

export function createPatchFunction (backend) {

    // 省略好多代码

    return function patch (oldVnode, vnode, hydrating, removeOnly) {

        // 省略好多代码

    }

}

이벤트 루프

네 가지 개념 :

  1. 동기 작업 : 메인 스레드에서 실행 대기중인 작업. 다음 작업을 실행하기 전에 이전 작업 만 완료됩니다.

  2. 비동기 작업 : 특정 비동기 작업은 메인 스레드에 들어 가지 않고 실행할 수 있으며, 작업은 실행을 위해 메인 스레드로 들어갑니다.

  3. macrotask : 주요 시나리오에는 기본 코드 블록, setTimeout, setInterval 등이 포함됩니다.

  4. 마이크로 태스크 : 주요 시나리오에는 Promise, process.nextTick 등이 포함됩니다.

이 점에 대해서는 이미 많은 온라인 자습서가 있으며 공간 문제 때문에 여기서는 자세히 설명하지 않겠습니다.

매우 상세한 기사를 추천합니다.

자바 스크립트 실행 메커니즘 : https://juejin.im/post/59e85eebf265da430d571f89#heading-4

요약하자면

이 기사는 여기에 있습니다. 하지만 제가 할 말이 하나 있는데,이 기사의 위치는 모든 측면에서 모든 지식을 설명하는 것이 아니라 비현실적이며 그러한 능력이 없습니다.

이 기사를 통해 요점을 알려 드리고자합니다. 소스 코드를 보려면 필수 JavaScript 기본 지식이 확실해야합니다. 그렇지 않으면 어려움을 겪을 것입니다.

매일 발전하기를 바랍니다.

Vue 관련 기사 출력 계획

최근에는 친구들이 항상 Vue 관련 질문에 대해 물어 보셨 기 때문에 다음에 Vue 관련 기사 9 개를 출력 해 드리겠습니다. 7 ~ 10 일 내에 업데이트를 유지하겠습니다.

  1. [프론트 엔드 사전] Vuex, Vue 라이프 사이클 프로세스 주입 (완료)

  2. [프론트 엔드 사전] Vue 반응 원리 분석

  3. [프론트 엔드 사전] 신규 및 기존 VNode 패치 프로세스

  4. [프론트 엔드 사전] 기능성 컴포넌트 개발 및 npm 업로드 방법

  5. [프런트 엔드 사전] 이러한 측면에서 Vue 프로젝트 최적화

  6. [프론트 엔드 사전] Vue-Router 설계에서 프론트 엔드 라우팅 개발에 대해 이야기

  7. [프런트 엔드 사전] 프로젝트에서 Webpack을 올바르게 사용하는 방법

  8. [프런트 엔드 사전] Vue 서버 렌더링

  9. [프런트 엔드 사전] Axios와 Fetch 중 선택하는 방법

내 공식 계정에 주목 해주시면 가능한 한 빨리 최신 기사를 받아보실 수 있습니다.

[프런트 엔드 사전] Vue 소스 코드 학습에 필요한 지식 보유

그룹 커뮤니케이션에 참여하려면 스마트 로봇을 추가하여 자동으로 그룹에 참여할 수도 있습니다.

[프런트 엔드 사전] Vue 소스 코드 학습에 필요한 지식 보유

자유롭게 행복하세요

추천

출처blog.51cto.com/15077552/2596451