了解Vue

(1)_toString

function _toString (val) {
  return val == null
    ? ''
    : typeof val === 'object'
      ? JSON.stringify(val, null, 2)
      : String(val)
}

這個函數(shù)還是比較好理解的,如果傳入的值為空,則返回空字符串;否則,如果傳入的是對象,則將其變?yōu)?JSON 的數(shù)據(jù)格式(強調(diào):JSON 是字符串!);否則以字符串的形式輸出。

這里面,我們需要學(xué)習(xí)的是 JSON.stringify(val, null, 2) 這個方法,其中的 2 表示縮進為 2 個空格,其中的第二個 null 參數(shù)表示序列化,如果為 null 則表示所有屬性都被序列化。
(2) toNumber

function toNumber (val) {
  var n = parseFloat(val);
  return isNaN(n) ? val : n
}

該函數(shù)表示將傳入的值轉(zhuǎn)化為數(shù)值,如果傳入的不是數(shù)字,則返回這個值。這里面,我們需要了解到 parseFloat 這個函數(shù),返回它遇到的第一個不是數(shù)字的前面的所有數(shù)字。

比如說:parseFloat('123ab'),返回的是 123;parseFloat('ab123') 則返回 NaN 。

所以,這也是為什么這里使用了 isNaN() 這個函數(shù)。當(dāng)然,在 ES6 的規(guī)范中,建議還是使用 Number.isNaN() 和 Number.parseFloat() 更好。
(3)makeMap

function makeMap (
  str,  //  字符串
  expectsLowerCase  // 轉(zhuǎn)換為小寫
) {
  var map = Object.create(null);
  var list = str.split(',');
  for (var i = 0; i < list.length; i++) {
    map[list[i]] = true;
  }
  return expectsLowerCase
    ? function (val) { return map[val.toLowerCase()]; }
    : function (val) { return map[val]; }
}
// 檢查 tag 標(biāo)簽是否為內(nèi)置的標(biāo)簽
var isBuiltInTag = makeMap('slot,component', true);

關(guān)于這個函數(shù),官方的說法是:創(chuàng)建一個 map 并返回一個函數(shù)以確定是否該鍵存在于這個 map 中。至少目前,我們看不出它的作用來,后面用到了再說吧。

其中我們需要學(xué)習(xí)到 Object.create() 這個方法是干什么的,它和 new Object() 有什么區(qū)別。Object.create() 這個方法的用處就是創(chuàng)建一個對象,它可以繼承指定的原型。比如說,我有一個對象:

Object.create(null, {
   a: {
     value: 1
   }
 }

它等價于:

const obj = {
  a: 1
}

記住,這是錯誤的!因為我們這里設(shè)置的第一個參數(shù)為 null,那么這個對象是沒有原型的!也就是說,它沒有對象原型上的方法。如果要等價的話,那么我們的參數(shù)要設(shè)置為 {}。

Object.create({}, {
   a: {
     value: 1
   }
 }

這樣,才是等價的。

在這里,設(shè)置為 null 的意思就是說,創(chuàng)建一個沒有原型的對象。
(4)remove$1

function remove$1 (arr, item) {
  if (arr.length) {
    var index = arr.indexOf(item);
    if (index > -1) {
      return arr.splice(index, 1)
    }
  }
}

這個函數(shù)的意思是,從數(shù)組中移除掉一個值。這個函數(shù)很典型。首先,如果它是一個數(shù)組,那么則找到想要的這個值第一次出現(xiàn)時的索引值;如果數(shù)組中存在這個值,那么就使用 splice() 這個方法將其移除并返回。

我們來測試一下這個方法:

remove$1([1, 2, 3], 2)
// 返回 [2],原數(shù)組變?yōu)閇1, 3]
remove$1([1, 2, 3, 2], 2)
// 返回 [2],原數(shù)組變?yōu)閇1, 3, 2]

這個函數(shù)我們平時也是可以用到的,但是這個函數(shù)呢,只能返回第一個被查詢到的值。這是 indexOf() 這個函數(shù)的局限性,記住這一點。
(5)hasOwnProperty

var hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn (obj, key) {
  return hasOwnProperty.call(obj, key)
}

這個函數(shù)的作用是檢查該屬性是否是這個對象所擁有的。說的更加直白一點就是,對象是否有這個鍵(key),我們來測試一下:

const obj = {
   a: 1,
   b: 2
 };
 console.log(hasOwn(obj, 'c'));  // false
 console.log(hasOwn(obj, 'a'));  // true

這個 obj 中是沒有 c 這個鍵的。這個是被封裝起來的函數(shù),平時如果單獨使用的話,則可以直接調(diào)用 Object.prototype.hasOwnProperty() 這個方法的。
(6)isPrimitive

function isPrimitive (value) {
  return typeof value === 'string' || typeof value === 'number'
}

該函數(shù)是判斷該值是否為原始值。

原始值有六種類型,分別為 String、Number、Boolean、Symbol、Null 和 Undefined。

當(dāng)然這里只判斷了該值是字符串還是數(shù)值類型。
(7)cached

function cached (fn) {
  var cache = Object.create(null);
  return (function cachedFn (str) {
    var hit = cache[str];
    return hit || (cache[str] = fn(str))
  })
}

這個方法的作用是創(chuàng)建一個純函數(shù)的緩存版本。單獨看,肯定是看不懂這個函數(shù)想表達(dá)一個什么意思。來,我們接著往下看:

(1)駝峰化以連字符分隔的字符串。

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

(2)大寫字符串。

var capitalize = cached(function (str) {
  return str.charAt(0).toUpperCase() + str.slice(1)
});

(3)連接駝峰命名的字符串。

var hyphenateRE = /([^-])([A-Z])/g;
var hyphenate = cached(function (str) {
  return str
    .replace(hyphenateRE, '$1-$2')
    .replace(hyphenateRE, '$1-$2')
    .toLowerCase()
});

我們先不看上面三個代碼,我們先來試著理解 cache() 這個函數(shù)。這個函數(shù)是干什么的?在 JavaScript 中,有一個很經(jīng)典的函數(shù)寫法叫做 “緩存策略”,它是用來加速我們的數(shù)據(jù)的讀取速度的。

它的實現(xiàn)原理:創(chuàng)建一個對象,將我們所寫的東西保存到這個對象中,如果說我們后面再次用到了這個東西,那么 JavaScript 就不需要再計算一遍了,直接將這個對象中我們需要的東西提取出來就好了。

這是提高執(zhí)行速度的一種十分有效的辦法,可以作為了解,很多的庫都會用到它。
(8)bind$1

function bind$1 (fn, ctx) {
  function boundFn (a) {
    var l = arguments.length;
    return l
      ? l > 1
        ? fn.apply(ctx, arguments)
        : fn.call(ctx, a)
      : fn.call(ctx)
  }
  // 記錄原始的 fn 長度
  boundFn._length = fn.length;
  return boundFn
}

該函數(shù)的作用與原生的 bind() 方法一致,但官方說,這個函數(shù)比原生要快。其中的 ctx 參數(shù)的意思是 context,即上下文。其實也就是我們常使用的 this 指定的上下文環(huán)境。
(9)toArray

function toArray (list, start) {
  start = start || 0;
  var i = list.length - start;
  var ret = new Array(i);
  while (i--) {
    ret[i] = list[i + start];
  }
  return ret
}

該方法將一個類數(shù)組對象轉(zhuǎn)換成真正的數(shù)組對象。其中的 list 表示類數(shù)組對象,而 start 表示起始的索引值。當(dāng)然,我們的 ES6 中的 Array.from() 也可以轉(zhuǎn)換,可是它不能指定起始的位置。

我們來測試一下:

console.log(toArray({
   0: 'a',
   1: 'b',
   2: 'c',
   length: 3
}, 1));
// ["b", "c"]

當(dāng)然了,其實我們使用 ES6 同樣可以達(dá)到這個效果。我來寫一個能達(dá)到同樣效果的函數(shù)吧:

function toArray(list, start = 0) {
   const realArray = Array.from(list);
   return realArray.slice(start);
}

不僅如此,我還可以設(shè)置結(jié)束的位置:

function toArray(list, start = 0, end = list.length) {
  const realArray = Array.from(list);
  return realArray.slice(start, end);
}

好了,這個函數(shù)就到此結(jié)束啦。
(10)extend

function extend (to, _from) {
  for (var key in _from) {
    to[key] = _from[key];
  }
  return to
}

該函數(shù)的作用是:將屬性混合到目標(biāo)對象中。說的直白一點就是拷貝對象的屬性。

比如我這里有一個空對象,還有另一個對象,將另一個對象中的屬性拷貝到這個空對象中去:

const a = {};
const b = {
  a: 1,
  b: 2
 };
extend(a, b);
console.log(a);  // {a: 1, b: 2}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,679評論 0 4
  • 本來打算睡覺的,但突然想到今天需要寫日記,于是只能加加班了。 上班開始的時候,看了下百度貼吧,搜了京東金融,主要是...
    轉(zhuǎn)瞬之夏的日記本閱讀 274評論 0 0
  • 過完年后,二月份來到這個古都找工作,在朋友的介紹下去梨城,那里的一切都是很好,風(fēng)景氣候美麗極咯。 好景不常...
    梧桐樹的藍(lán)閱讀 275評論 0 0
  • dlgd閱讀 160評論 0 0
  • 平息若無閒來時, 浮雲(yún)捲雲(yún)一陣風(fēng). 庭外知了聲聲唱, 酒水幾人一杯杯.
    荒木覺閱讀 393評論 7 6

友情鏈接更多精彩內(nèi)容