call()方法在数组中的一次应用分析

call()方法在数组中的一次应用分析

call()方法在数组中的一次应用分析

weixin_34212762 2019-05-16 14:04:45   348   收藏
版权
在阅读别人代码时, call和apply是常客。今天遇到一行代码 [].slice.call(arguments) 让我想真正了解一下它的含义。

一、看一下它的作用
let arr = [1, 2, 3, 4]
console.log([].slice.call(arr))
复制代码
结果:

可以看到, 结果是它本身.

添加参数:

 可以看到添加参数后,生效的是前两位。所以猜测,其作用是和slice()函数基本一样。
根据call()的定义, 其根本是改变this指向,那么第一个参数就是slice()this,后续则为参数。

为了更好的理解,我们重写Array的slice方法并打印:
结果
所以我们可以基本确定他是改变slice()this。那么真的是么?我们一起看看源码

二、slice()源码简单分析
我们来看看Array的slice源码。 源码地址:V8 Array.js 587function 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)。

三、思考开始
但这儿我们可以猜到,那我们传入字符是否能转换成数组并返回呢?我们来试一试

一、使用[].slice.call(Str)
结果如我们所料,他可以让我们字符串转换成数组返回。

二、使用 slice方法.
如果我们直接使用slice方法

 答案肯定是不行的,因为String和Array都有各自的slice()方法,如果要实现只有重写String方法,或者将Array的slice方法赋给String对象。 
所以为了更好的利用slice()的方法,第二种方法显得更加麻烦。这也是第一种方法的妙用,这就更能加深我个人对call和apply的使用印象(apply应用同理)。

三、那么我们传入一个对象可以吗?
一起试试

 答案是可以但是,有几个条件。 再次观察源码可知:
1) 需要Length长度
2) 需要Key值为下标(应该是TO_OBJECT()方法生成是以for...in循环,依靠下标遍历生成的,望大佬能指正)
 所以这两种方法都只能返回一个空数组。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值