类数组对象
所谓的类数组对象:拥有一个length属性和若干索引属性的对象
var arr = ['name', 'age', 'sex']
var arrLike = {
0: 'name',
1: 'age',
2: 'sex',
length: 3
}
我们从读写、获取长度、遍历三个方面看看这两个对象。
读写
console.log(arr[0]) // name
console.log(arrLike[0]) // name
arr[0] = 'new name'
arrLike[0] = 'new name'
长度
console.log(arr.length) // 3
console.log(arrLike.length) // 3
遍历
for(var i = 0, len = arr.length; i<len; i++) {
console.log(arr[i])
// name age sex
}
for(var i = 0, len = arrLike.length; i<len; i++) {
console.log(arr[i])
// name age sex
}
调用数组方法
类数组可以调用数组的方法吗?
arrLike.push('city')
// arrLike is not a function
类数组无法直接调用数组方法,我们可以用Function.call间接调用
console.log(Array.prototype.join.call(arrLike, '&')) // name&age&sex
console.log(Array.prototype.slice.call(arrLike)) // ['name','age','sex']
// slice可以做到类数组转数组
console.log(Array.prototype.map.call(arrLike, function(item){
return item.toUpperCase()
})) // ['NAME','AGE','SEX']
类数组转数组
上面的例子已经提到一种类数组转数组的方法,再补充完善下:
console.log(Array.prototype.slice.call(arrLike))
console.log(Array.prototype.splice.call(arrLike, 0))
// ES6
console.log(Array.from(arrLike))
console.log(Array.prototype.concat.apply([], arrLike))
Arguments对象
Arguments对象就是一个类数组对象,Arguments对象只定义在函数体内,包括了函数的参数和其他参数。在函数体中,arguments指代该函数的Arguments对象。
function foo(name, age, sex) {
console.log(arguments)
}
foo('name', 'age', 'sex')
打印结果:

我们看到除了类数组的索引属性和length属性之外,还有一个callee属性。
length属性
Arguments对象的length属性,表示实参的长度
function foo(name, age, sex) {
// 实参长度
console.log(arguments.length) // 1
}
// 形参长度
console.log(foo.length) // 3
foo('name')
callee属性
Arguments对象的callee属性,通过它可以调用函数自身。
通过下面闭包的例子来看下callee的解决方法:
var data = []
for(var i = 0; i < 3; i++) {
(data[i] = function() {
console.log(arguments.callee.i)
}). i = i
}
console.log(data[0].i) // 0
console.log(data[1].i) // 1
console.log(data[2].i) // 2
arguments和对象参数的绑定
function foo(name, age, sex, hobbit) {
console.log(name, arguments[0]) // name, name
// 改变形参
arguments[0] = 'new name'
console.log(name, arguments[0]) // new name, new name
// 改变arguments
arguments[1] = 'new age'
console.log(name, arguments[1]) // new name, new age
// 未传入的是否会被绑定
sex = 'new sex'
console.log(sex, arguments[2]) // undefined, new sex
arguments[3] = 'new hobbit'
console.log(hobbit, arguments[3]) // undefined, new hobbit
}
foo('name', 'age')
传入的参数,实参和arguments的值会被共享,当没有传入的时候,实参与arguments不会共享。
以上都是非严格模式下,在严格模式下,实参和arguments是不会共享的。
传递参数
将参数从一个函数传递到另一个函数
function foo(){
bar.apply(this, arguments)
}
function bar(a,b,c){
console.log(a,b,c)
}
foo(1,2,3) // 1,2,3
ES6展开运算符
function func(...arguments) {
console.log(arguments)
}
func(1,2,3) // 1,2,3
应用
arguments的应用其实很多,例如:
- 参数不定长
- 函数柯里化
- 递归调用
- 函数重载
- ......
网友评论