【JS】Array.prototype.join.call(arguments,',')解析

666 阅读2分钟

定义

arguments 是一个对应于传递给函数的参数的类数组对象

注意:它是一个类似数组的对象,本质上还是对象,console.log(typeof arguments)输出的是object

简要回顾

  1. arguments主要有三个注意的地方:lengthcallee(指向当前函数,可用于迭代),索引元素
  2. arguments除了length属性和索引元素之外没有任何Array属性。

例子解析

Array.prototype.join.call(arguments,',')

首先我们要明白如下几个事情:

  1. call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

说人话:call方法改变了this指向,即当前this指向了call函数第一个参数。

  1. arguments是一个对象,只是类似于数组,本身并不是数组,所以想要把它变成数组,要进行一定的转换。
  2. Array.prototype的类型是Array;Array.prototype即Array的原型对象,其下包含了join()方法

第三点可能有的同学不明白,那就简单介绍一下原型,见下图(摘自JS红皮书148页):

原型

function Person() {
}

Person.prototype.name = 'Nicholas'
Person.prototype.age = 29
Person.prototype.job = 'Software Engineer'
Person.prototype.sayName = function () {
    console.log(this.name)
}

var person1 = new Person()
person1.sayName()   //Nicholas

var person2 = new Person()
person1.sayName()   //Nicholas

console.log(person1.sayName == person2.sayName)  //true
  1. 创建了两个实例person1,person2,他们分别指向了Person的原型对象Person Prototype。
  2. 原型对象Person Prototype有一个默认的constructor属性,指向Person本身。
  3. 原型对象Person Prototype有一个名字叫sayName的函数,还有其他name,age,job三个属性。
  4. person1作为一个实例,调用方法sayName,但是person1所在的存储空间,本身没有sayName方法,所以person1会顺着原型链寻找,直到找到Person Prototype中的sayName方法。

类似地,如法炮制Array,这个JS内置引用类型

  1. 平时我们常用 var arr = new Array() , 创建一个名为arr的Array实例。
  2. 我们使用arr.push(),arr.join(','),arr.concat(anotherArray)等等一系列Array“自带”的方法。arr实例本身没有这些方法,所以它就会顺着原型链寻找,寻找到Array Prototype,发现了这些方法,所以这些方法都是原型对象Array Prototype上的

书归正传,这就解释了Array.prototype.join()这个方法的存在性。

Array.prototype.join.call(arguments,',')

所以这里无非把Array的原型对象Array Prototype中的join(),进行了调用;只不过调用的时候,通过call(),将this的指向arguments,对arguments进行了处理和转换。最后结果是arguments每个索引元素中间拼接了逗号的字符串

额外的话

其实把arguments转换为数组,JS本身还提供了from方法,还有ES6的解构赋值。

var args = Array.from(arguments)
var args = [...arguments]

所以,

var str = Array.prototype.join.call(arguments,',')

也可等价于如下代码

var args = Array.from(arguments)  //将arguments转换为数组
var str = args.join(',')

Thanks for reading......