这个系列是我读冴羽老师博客的感悟,
加入了个人的解读和练习题的解答
类数组
在之前模拟实现apply和bind时我们其实已经遇见过arguments这样的类数组文件了
1
2
3
4
5
6
7
|
var array = ['A', 'B', 'C']
var arrayLike = {
0: 'A',
1: 'B',
2: 'C',
lenght: 3
}
|
类数组文件的读取,遍历方式和数组一样
1
2
3
4
5
6
7
8
|
array[0]
arrayLike[0]
array.length
arrayLike.length
for(var i=0; i<array.length; i++){}
for(var i=0; i<arrayLike.length; i++){}
|
但是类数组终究不是数组不能调用数组的原型方法,比如push、splice、slice
常用的做法是Array.prototype.splice.call(arrayLike, 2)
利用call在直接调用Array原型方法的时候把this指向arrayLike对象
另外经常需要把类数组对象转为数组,方法如下:
1
2
3
4
5
|
Array.prototype.slice.call(arrayLike) //slice 用于截取数组从start到end,省略end时默认到数组末尾
Array.prototype.splice.call(arrayLike, 0) //splice 可以插入删除,参数index, deleteNumber, item1,...,itemX
Array.prototype.concat.call([], arrayLike)
Array.from(arrayLike) //es6 Array.from
[...arguments] //es6 拓展运算符
|
Aruguments对象
在函数体中arguments指代函数的Arguments对象
Aruguments的length,指的是实参的长度
Arguments的callee通过它可以调用函数本身
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//用callee来解决之前第8篇中的for循环无法保存i到函数内部的问题
var data = []
for (var i = 0; i< 3; i++) {
(data[i] = function(){
console.log(arguments.callee.i)
).i = i
}
data[0](); //0
data[1](); //1
data[2](); //2
|
乍一看在for循环中的那部分有点奇怪,我们拆开看
xxx.i = i 是在xxx的属性i赋值为i
括号内:
data[i] = 某个东西
(data[i] = 赋值内容).i = i 其实就是
data[i].i = i
接下来看赋值的内容
是一个函数对象,函数对象在创建的时候不会执行内部的代码
argument.callee 指的就是 data[i]
argument.callee.i 自然就是data[i].i
那因为纯的赋值 = xx 会在for循环里立即执行,所有i的每个状态都会存在对应的data[x]里
arguments 和对应参数的绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
function foo(name, age, sex, hobbit) {
console.log(name, arguments[0]); // name name
// 改变形参
name = 'new name';
console.log(name, arguments[0]); // new name new name
// 改变arguments
arguments[1] = 'new age';
console.log(age, arguments[1]); // new age new age
// 测试未传入的是否会绑定
console.log(sex); // undefined
sex = 'new sex';
console.log(sex, arguments[2]); // new sex undefined
arguments[3] = 'new hobbit';
console.log(hobbit, arguments[3]); // undefined new hobbit
}
foo('name', 'age')
|
传入参数时,实参和arguments的值会共享,没有传入参数时,实参和arguments的值不会共享
在严格模式下都不会共享
传递参数
将参数从一个函数传递到另一个函数
1
2
3
4
5
6
7
8
9
|
//利用apply的第二个参数可以直接传一个数组
function foo(){
bar.apply(this, [...arguments])
}
function bar(){
console.log(a, b, c)
}
foo(1, 2, 3)
|