call()方法在數組中的一次應用分析

在閱讀別人代碼時, call和apply是常客。今天遇到一行代碼 [].slice.call(arguments) 讓我想真正瞭解一下它的含義。javascript

1、看一下它的做用

let arr = [1, 2, 3, 4]
console.log([].slice.call(arr))
複製代碼

結果: java

能夠看到, 結果是它自己.git


添加參數: github

能夠看到添加參數後,生效的是前兩位。因此猜想,其做用是和slice()函數基本同樣。


根據call()的定義, 其根本是改變this指向,那麼第一個參數就是slice()的this,後續則爲參數。數組

爲了更好的理解,咱們重寫Array的slice方法並打印:

結果

因此咱們能夠基本肯定他是改變slice()的this。那麼真的是麼?咱們一塊兒看看源碼app

2、slice()源碼簡單分析

咱們來看看Array的slice源碼。 源碼地址:V8 Array.js 587行函數

function ArraySlice(start, end) {
  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");

  var array = TO_OBJECT(this); // 轉換爲數組!! 獲取的是This.
  var len = TO_LENGTH(array.length);
  var start_i = TO_INTEGER(start);
  var end_i = len;
// 範圍界定 start
  if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end);

  if (start_i < 0) {
    start_i += len;
    if (start_i < 0) start_i = 0;
  } else {
    if (start_i > len) start_i = len;
  }

  if (end_i < 0) {
    end_i += len;
    if (end_i < 0) end_i = 0;
  } else {
    if (end_i > len) end_i = len;
  }
// 範圍界定 end
// 數組處理 start
  var result = ArraySpeciesCreate(array, MaxSimple(end_i - start_i, 0));

  if (end_i < start_i) return result;

  if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
    %NormalizeElements(array);
    if (IS_ARRAY(result)) %NormalizeElements(result);
    SparseSlice(array, start_i, end_i - start_i, len, result);
  } else {
    SimpleSlice(array, start_i, end_i - start_i, len, result);
  }

  result.length = end_i - start_i;
// 數組處理 end
  return result; // 返回一個數組
}
複製代碼

觀察可知。Array的slice方法會經過TO_OBJECT(this)方法把傳入的內容轉換爲數組。因此咱們以前的分析是到位的。 由於大部分其封裝的方法沒有找到,因此只能靠命名判斷(吐血.jpg)。ui

3、思考開始

但這兒咱們能夠猜到,那咱們傳入字符是否能轉換成數組並返回呢?咱們來試一試this

1、使用[].slice.call(Str)

結果如咱們所料,他可讓咱們字符串轉換成數組返回。 spa

2、使用 slice方法.

若是咱們直接使用slice方法

答案確定是不行的,由於String和Array都有各自的slice()方法,若是要實現只有重寫String方法,或者將Array的slice方法賦給String對象。

因此爲了更好的利用slice()的方法,第二種方法顯得更加麻煩。這也是第一種方法的妙用,這就更能加深我我的對call和apply的使用印象(apply應用同理)。

3、那麼咱們傳入一個對象能夠嗎?

一塊兒試試

答案是能夠可是,有幾個條件。 再次觀察源碼可知:

1) 須要Length長度
2) 須要Key值爲下標(應該是TO_OBJECT()方法生成是以for...in循環,依靠下標遍歷生成的,望大佬能指正)

因此這兩種方法都只能返回一個空數組。

如下就是個人我的看法,但願有大佬能指正。 第一次技術文章,但願會愈來愈好。

相關文章
相關標籤/搜索