Некоторые полезные функции в исходном коде Vue

Vue.js

Многие библиотеки с открытым исходным кодом в JS имеют папку util для хранения некоторых часто используемых функций. Эти подпрограммы часто используются, но не входят в спецификацию ES, и их недостаточно, чтобы опубликовать модуль npm только для них. Поэтому многие библиотеки будут писать отдельный функциональный модуль инструмента.

Самые продвинутые попробуйте прочитать исходный код vue, увидите много интересных функций, поделитесь ими здесь.

Разница между Object.prototype.toString.call(arg) и String(arg)?

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

String(arg) попытается вызвать arg.toString() или arg.valueOf(), поэтому, если прототип arg или arg переопределяет эти два метода, Object.prototype.toString.call(arg) и String(arg) результат другой

const _toString = Object.prototype.toString
var obj = {}

obj.toString()  // [object Object]
_toString.call(obj) // [object Object]

obj.toString = () => '111'

obj.toString()  // 111
_toString.call(obj) // [object Object]

/hello/.toString() // /hello/
_toString.call(/hello/) // [object RegExp]

Вышеприведенное изображение является скриншотом ES2018, мы можем знать правила Object.prototype.toString, и есть правило, возвращаемое значение Object.prototype.toString всегда равно[object + tag + ], если нам нужен только средний тег, а не раздражающие дополнительные символы с обеих сторон, мы можем

function toRawType (value) {
  return _toString.call(value).slice(8, -1)
}

toRawType(null) // "Null"
toRawType(/sdfsd/) //"RegExp"

Хотя это кажется очень простым, трудно спонтанно понять этот способ письма. .

Результаты расчета функции кэширования

Если есть такая функция

function computed(str) {
  // 假设中间的计算非常耗时
  console.log('2000s have passed')
  return 'a result'
}

Мы хотим закэшировать некоторые результаты операции, и напрямую читать содержимое кеша при втором вызове, как мы можем это сделать?

function cached(fn){
  const cache = Object.create(null)
  return function cachedFn (str) {
    if ( !cache[str] ) {
        cache[str] = fn(str)
    }
    return cache[str]
  }
}

var cachedComputed = cached(computed)
cachedComputed('ss')
// 打印2000s have passed
cachedComputed('ss')
// 不再打印

Будуhello-worldпревращение стиля вhelloWorldстиль

const camelizeRE = /-(\w)/g
const camelize = cached((str) => {
  return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})

camelize('hello-world')
// "helloWorld"

Определяем рабочую среду JS

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+)/)

Определите, предоставляется ли функция хост-средой или определяется пользователем.

console.log.toString()
// "function log() { [native code] }"

function fn(){}
fn.toString()
// "function fn(){}"

// 所以
function isNative (Ctor){
  return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
}