В процессе нашего интервью мы часто сталкиваемся со ссылкой на вопрос об исходном коде, потому что отличные фреймворки обычно содержат много концепций дизайна и практик программирования. Я смотрел все это времяVue2, нашел много интересных реализаций. Хотя сейчасVue3Это было опубликовано, и это нельзя отрицать.Vue2Тот факт, что это превосходный фреймворк, не мешает нам учиться у него некоторым передовым практикам.
правильноVueСтуденты, которые не заинтересованы, также могут взглянуть, потому что я просто говорю о том, что я узнал из реализации этого фреймворка.JavaScriptиспользования, не включаетVueКонцепция чего-либо.
- Получить текст без метки в виде строки в формате HTML (vue/src/compiler/parser/entity-decoder.js)
Предположим, у нас есть такая строка:
var html = '<span class="red">hello world</span> <span>hello xxx</span>'. Теперь мы хотим извлечь непомеченный текст и получить следующие результаты:
'hello world hello xxx'. Как это сделать? Сначала мы должны подумать о регулярных выражениях, но в этом сценарии регулярные выражения должно быть очень утомительно писать, давайте посмотримVueКак разработчики:
- Так как эта строка
HTMLтекстовый формат, мы можем разобрать его в соответствующийHTMLэлемент. -
HTMLэлементальtextContentсвойства можно использовать для полученияHTMLТекстовое содержимое элемента.
код показывает, как показано ниже:
function decoder(html){
let decoder = document.createElement('div')
decoder.innerHTML = html
console.log(decoder.textContent)
// return decoder.textContent
}
Этот код создаетdivэлемент как контейнер, затем установивinnerHTMLпреобразовать строку в соответствующийHTMLэлемент, и, наконец, вы можете передатьtextContentсвойство для получения текстового содержимого.
- Определить рабочую среду (vue/src/core/util/env.js)
Благодаря быстрой разработке внешнего интерфейса мы уже можем работать в нескольких средах.JavaScriptКод, чтобы приспособиться к различным операционным средам, нам нужно знать, в какой среде работает наш код, давайте посмотримVueКак определяется среда выполнения:
const inBrowser = typeof window !== 'undefined'
const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()
const UA = inBrowser && window.navigator.userAgent.toLowerCase()
const isIE = UA && /msie|trident/.test(UA)
const isIE9 = UA && UA.indexOf('msie 9.0') > 0
const isEdge = UA && UA.indexOf('edge/') > 0
const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android')
const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios')
const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
const isPhantomJS = UA && /phantomjs/.test(UA)
const isFF = UA && UA.match(/firefox\/(\d+)/)
Если бы наш код работал в браузере, мы бы обязательно получилиwindowобъект, поэтому мы можем пройтиconst inBrowser = typeof window !== 'undefined'Это способ судить об окружающей среде.
И в браузере мы можем пройтиwindowОбъект получаетuserAgent,для разных браузеров
userAgentтоже разные вродеIEизuserAgentвсегда будет содержатьMSIE,а такжеChromeизuserAgentбудет содержатьChrome. Подобный браузерuserAgentпринесуAndroid. тогда мы проходимuserAgentВы можете определить, какой браузер вы используете в данный момент и в какой операционной системе он работает. В приведенном выше коде перечислены суждения основных браузеров и операционных систем.Обратите внимание, что из-заEdgeПоследняя версия браузера также основана наChromiumядро, поэтому егоuserAgentтакже будет содержатьChromeИтак, мы пишемconst isChrome = UA && /chrome\/\d+/.test(UA) && !isEdgeТакой код для определения того, является ли текущая средаChrome.
- Определить, является ли функция определяемой пользователем (vue/src/core/util/env.js)
Как правило, мы используем два вида функций: те, которые предоставляет нам среда, и те, которые определяются самими нашими пользователями.Выражения этих двух функций различаются, когда они преобразуются в строки:
Array.isArray.toString() // "function isArray() { [native code] }"
function fn(){}
fn.toString() // "function fn(){}"
Среда поставляется с вызовами функцийtoStringметод всегда будет возвращать что-то вродеfunction fnName() { [native code] }строка формата, мы можем использовать это, чтобы различать типы функций:
function isNative (Ctor){
return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
}
- Реализуйте функцию, которая выполняется только один раз (vue/src/shared/util.js)
Много раз нам нужно, чтобы функция выполнялась только один раз, даже если она вызывается несколько раз, будет выполнен только первый вызов, поэтому мы можем написать следующий код:
function once (fn) {
let called = false
return function () {
if (!called) {
called = true
fn.apply(this, arguments)
}
}
}
Таким образом, мы пропустим его напрямую, когда будем выполнять его позже.Это реализовано с помощью функций высшего порядка.Если вам интересно, вы можете прочитать мою предыдущую статью.Дополнительные советы по JavaScript. Давайте протестируем этот метод:
можно увидетьtestМетод выполняется только один раз.
- Кэшировать результаты выполнения функции (vue/src/shared/util.js)
Об этом я также упоминал в предыдущем блоге, иногда выполнение функции отнимает много времени, мы хотим закешировать результат выполнения. Таким образом, когда он вызывается позже, если параметры совпадают, мы можем пропустить вычисление и вернуть результат напрямую. Все, что нам нужно, это реализоватьcachedФункция, которая принимает фактическую вызываемую функцию в качестве аргумента и возвращает обернутую функцию. в этотcachedфункцию, мы можем использовать объект илиMapкэшировать результаты.
function cached(fn){
const cache = Object.create(null);
return function cachedFn (str) {
if ( !cache[str] ) {
let result = fn(str);
cache[str] = result;
}
return cache[str]
}
}
- Преобразовать стиль именования (vue/src/shared/util.js)
У каждого из нас могут быть разные стили программирования. Кому-то нравится верблюжий случай, а кому-то нравятся маленькие горизонтальные соединители. Чтобы решить эту проблему, мы можем написать функцию для унифицированного преобразования. (например, преобразование a-b-c в aBC)
const camelizeRE = /-(\w)/g
const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})
camelize('a-b-c')
// "aBC"
- определить тип объекта (vue/src/shared/util.js)
В JavaScript существует шесть основных типов (Boolean, Number, String, Null, Undefined, Symbol) и тип объекта, но на самом деле типы объектов можно разделить на множество типов: объект может быть массивом или функцией и т. д. . Есть ли способ получить его точный тип?
мы можем использоватьObject.prototype.toStringПреобразовать объект в строку, если мы используем{}созданный объект, этот метод всегда возвращает[object Object].
Для массивов, регулярных выражений и других типов объектов, поставляемых со средой, они будут возвращать разные результаты.
По этой характеристике мы можем определить, находится ли объект у нас{}Объекты созданы:
function isPlainObject (obj){
return Object.prototype.toString.call(obj) === '[object Object]'
}
И мы это заметили,Object.prototype.toString()Возвращаемое значение всегда начинается с[object tag]в виде, если мы только хотим этогоtag, мы можем исключить другие вещи, проще использовать обычные илиString.prototype.slice()Все будет хорошо.
function toRawType (value) {
const _toString = Object.prototype.toString
return _toString.call(value).slice(8, -1)
}
toRawType(null) // "Null"
toRawType(/sdfsd/) //"RegExp"
Таким образом, мы можем получить тип переменной.
- Преобразовать значение в строку (vue/src/shared/util.js)
Нам часто нужно преобразовать значение в строку, вJavaScriptВнутри у нас есть два способа получить строку:
- String()
- JSON.stringify()
Однако механизм реализации этих двух методов отличается:

Мы видим, что они преобразуют строки на основе совершенно разных правил,String(arg)попробую позвонитьarg.toString()илиarg.valueOf(), то какой из них мы должны использовать лучше?
-
для
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) }Это еще один плодотворный день. Читая код реализации отличных фреймворков, мы можем быстро улучшить наше использование языка, улучшить наше понимание некоторых функций и обобщить некоторые методы программирования. Наши способности программирования также практически качественно улучшились. настоятельно рекомендуется, чтобы при углубленном изучении языка вы читали превосходный код, реализованный на этом языке. для
JavaScriptИтак, мы только что обсудилиVueЕсть ли что-нибудь более увлекательное, чем изучение этих трех файлов с исходным кодом? Я надеюсь, что эта статья также может помочь вам, удачного кодирования~