那些在JS中你忽略到的概念(一):类数组、改变this

本文探讨了类数组的概念,如何将其转换为真正的数组,以及call、apply、bind在改变函数this指向的应用。重点介绍了伪数组的特性、类数组转数组的方法和push操作的实现原理,同时对比了call、apply和bind在重新定义this对象时的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值