1. 类数组/伪数组
- 可以通过索引进行访问,并且拥有length属性,其他属性为非负整数
- 没有数组的其他方法,例如push,forEach,indexOf
- 常见的类数组有: 函数的参数arguments、getElementBiTagName、getElementByClassName等方法获取到的dom列表、querySelectorAll()方法获取的所有NodeList节点
- 类数组转成真正数组的方法:1. Array.prototype.slice.call(arrayLike) 2. Array.from(arrayLike) 3. 扩展运算符 var arg = [...arrayLike]
- 类数组的push: 根据length来判断添加位置, 没有length的话,添加length, 默认length是0,此时push(0), 索引是0,对应值是0, length变成1, 再次push(1), 索引值是1,对应值是1
-
var foo = { 0: 'java', 1: 'Python', 2: 'Scala', 'length': 3, // 需要有length属性名 'push': Array.prototype.push // 最好有push属性 } // 如果类数组需要转化为数组,可以用 Array.prototype.slice.call // 伪数组是么有slice方法的,Array.prototype.slice.call(foo) 这个表达式相当于赋予foo这个对象slice方法 // 如果类数组要调用数组的方法,就需要使用Array.prototype.method.call实现 Array.prototype.forEach.call(foo, (item) => { }) // 类数组push的内部原理 Array.prototype.push = function(target){ this[this.length] = target; this.length ++; }
-
var foo = { 0: 'Vue', 1: 'java', 2: 'C', 3: 'js', length: 4, 'push': Array.prototype.push } foo.push('React')
var foo = { 1: 'zx', 2:'new', length: 1, 'push': Array.prototype.push } foo.push('test') // foo[1] = 'test' this.length+=1 length变成2 foo.push('vv') // foo[2] = 'vv' this.length+=1 length变成3
2. call、apply、bind区别
-
var name = 'zx', age = 18 let obj = { name: 'yx', objAge: this.age, // 指向window 18 myFun: function() { cosnole.log(this.name + '年龄' + this.age) // this指向 obj, yx年龄 undefined } } var str = 'test' function showStr() { cosnole.log(this.str) // this指向window test }
call()、apply()、bind()用来重新定义this对象的
var name = 'zx', age = 18 let obj = { name: 'yx', objAge: this.age, myFun: function(f,t) { console.log(this.name + '年龄' + this.age, '来自' + f + '去' + t) } } var realObj = { name: 'real', age: 28 } obj.myFun.call(realObj, '德州', '北京') //real年龄28 来自德州去北京 obj.myFun.apply(realObj, ['德州', '北京']) //real年龄28来自德州去北京 obj.myFun.bind(realObj,'德州', '北京')() //real年龄28 来自德州去北京bind返回的是一个新函数,必须调用才会被执行 applay可实现回去数组中最大值 Math.max(1,9,2) let arr = [1,9,2] Math.max.apply(Math, arr)