Изучение исходного кода Vue | 4 практических навыка Javascript

JavaScript
Изучение исходного кода Vue | 4 практических навыка Javascript

【Я впервые участвую в Gengwen Challenge9День, подробности о событии уточняйте:Обновить вызов"]

Очень эффективным способом изучения языка является чтение исходного кода отличных проектов с открытым исходным кодом, разработанных для этого языка программирования.Vuejsявляется одним из лучших проектов с открытым исходным кодом Javascript.

1. Преобразовать переменную в строку

vue/src/shared/util.js

Преобразование значения в строку является очень распространенной потребностью, в Javascript есть две функции для преобразования значения в строку:

  • String()
  • JSON.stringify()

Эти две функции имеют разные механизмы, см. следующий код:

console.log(String(null)); // null
console.log(JSON.stringify(null)); // null

console.log(String(undefined)); // undefined 这里是字符串
console.log(JSON.stringify(undefined)); // undefined 这里是变量

console.log(String("abc")); // abc
console.log(JSON.stringify("abc")); // "abc"

console.log(String({ key: "value" })); // [object Object]
console.log(JSON.stringify({ key: "value" })); // {"key":"value"}

console.log(String([1, 2, 3])); // 1,2,3
console.log(JSON.stringify([1, 2, 3])); // [1,2,3]

const obj = {
    title: "devpoint",
    toString() {
        return "obj";
    },
};
console.log(String(obj)); // obj
console.log(JSON.stringify(obj)); // {"title":"devpoint"}

Судя по приведенным выше результатам вывода, существуют различия в механизме преобразования объектов в строки между двумя методами.Как выбрать?

  • В реальной разработке нам необходимоnullа такжеundefinedПри преобразовании в строку часто требуется, чтобы она возвращала пустую строку.

  • Часто используется, когда вам нужно преобразовать массив и простой объект в строку.JSON.stringify.

  • Если вам нужен объектtoStringметод переопределен, вам нужно использовать String().

  • В остальных случаях используйтеString()Преобразование переменной в строку.

Чтобы выполнить вышеуказанные условия, исходный код Vue реализован следующим образом:

function isPlainObject(obj) {
    return Object.prototype.toString.call(obj) === "[object Object]";
}
function toString(val) {
    if (val === null || val === undefined) return "";
    if (Array.isArray(val)) return JSON.stringify(val);
    if (isPlainObject(val) && val.toString === Object.prototype.toString)
        return JSON.stringify(val);
    return String(val);
}

const obj = {
    title: "devpoint",
    toString() {
        return "obj";
    },
};
console.log(toString(obj)); // obj
console.log(toString([1, 2, 3])); // [1, 2, 3]
console.log(toString(undefined)); // ""
console.log(toString(null)); // ""

2. Обычные предметы

vue/src/shared/util.js

Object.prototype.toStringПозволяет преобразовывать объекты в строки. Для обычных объектов при вызове этого метода он всегда возвращает[object object].

const runToString = (obj) => Object.prototype.toString.call(obj);
console.log(runToString({})); // [object Object]
console.log(runToString({ title: "devpoint" })); // [object Object]
console.log(runToString({ title: "devpoint", author: { name: "devpoint" } })); // [object Object]

Назовем такой объект подобным вышеописанным обычным объектам.

В Javascript также есть некоторые специальные объекты, такие какArray,Stringа такжеRegExp, они имеют особый дизайн в движке Javascript. когда они звонятObject.prototype.toStringметод, вернет разные результаты.

const runToString = (obj) => Object.prototype.toString.call(obj);
console.log(runToString(["devpoint", 2021])); // [object Array]
console.log(runToString(new String("devpoint"))); // [object String]
console.log(runToString(/devpoint/)); // [object RegExp]

Чтобы отличить объекты специального дизайна от обычных объектов, можно использовать следующие функции.

function isPlainObject(obj) {
    return Object.prototype.toString.call(obj) === "[object Object]";
}

Часто нам нужно, чтобы функция выполнялась только один раз. Если функция вызывается несколько раз, она будет выполняться только в первый раз.

3.once

vue/src/shared/util.js

Часто нам нужно, чтобы функция выполнялась только один раз. Если функция вызывается несколько раз, она будет выполняться только в первый раз.

function once(fn) {
    let called = false;
    return function () {
        if (!called) {
            called = true;
            fn.apply(this, arguments);
        }
    };
}

function launchRocket() {
    console.log("我已经执行了");
}
const launchRocketOnce = once(launchRocket);
launchRocketOnce();
launchRocketOnce();
launchRocketOnce();

4. Анализ браузера

vue/src/core/util/env.js

Мы знаем, что Javascript может работать в браузерах, nodejs и т. д., так как же проверить, работает ли текущий код Javascript в среде браузера?

Если Javascript работает в среде браузера, существует глобальный объект:window. Таким образом, об окружающей среде можно судить по:

const inBrowser = typeof window !== "undefined";

Выполнить в Chrome

image.png

Выполнить в узле

image.png

Если скрипт работает в среде браузера, мы можем получитьuserAgent:

const UA = inBrowser && window.navigator.userAgent.toLowerCase();

Выполнить в Chrome

image.png

В разных браузерах разныеuserAgent. в Internet ExploreruserAgent, всегда содержит словоMSIEа такжеTridenт. в браузере ХромuserAgent, всегда включая слово Chrome.

Аналогично, в браузере ОС AndroiduserAgentВсегда включайте слово Android. В iOS всегда есть слово iPhone, iPad, iPod, iOS.

Поэтому, проверивuserAgentдля определения текущего поставщика браузера и операционной системы.

export const UA = inBrowser && window.navigator.userAgent.toLowerCase();
export const isIE = UA && /msie|trident/.test(UA);
export const isIE9 = UA && UA.indexOf("msie 9.0") > 0;
export const isEdge = UA && UA.indexOf("edge/") > 0;
export const isAndroid =  (UA && UA.indexOf("android") > 0) || weexPlatform === "android";
export const isIOS =  (UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform === "ios";
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
export const isPhantomJS = UA && /phantomjs/.test(UA);
export const isFF = UA && UA.match(/firefox\/(\d+)/);

В качестве примечания: и Edge, и Chrome основаны на Chromium, поэтому оба браузера имеютuserAgentВсе они содержат слово Chrome. То есть, когда браузерuserAgentКогда слово Chrome включено, браузер не обязательно является Chrome.const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge

над