一篇专门写数组和apply()和call()还有bind()方法的博客

数组精讲

本文在这里就不讨论数组的定义以及一些方法,主要讨论的是一些数组的面试方面常常考到的问题。

首先讲一下数组去重的问题

  var arr = [0, 0, 1, 2, 2, 3, 'a'];
        console.log(arr);
        var obj = {},
            newarr = [];
        Array.prototype.unique = function() {
            var length = this.length;
            for (var i = 0; i < length; i++) {
                if (!obj.hasOwnProperty(this[i])) {
                    obj[this[i]] = this[i];
                    newarr.push(this[i]);
                }
            }
            return newarr;
        }
        var uniquearr = arr.unique();

这段代码是通过给制造一个对象,然后通过是否有该键值来确定数组元素是否重复

字符串的去重

    var str = '112233rr';
        var obj = {},
            newstr = '';
        String.prototype.unique = function() {
            var length = this.length;
            for (var i = 0; i < length; i++) {
                if (!obj.hasOwnProperty(this[i])) {
                    obj[this[i]] = this[i];
                    newstr += this[i];
                }
            }
            return newstr;
        }
        var uniquearr = str.unique();
        console.log(uniquearr);

字符串的去重与数组的去重方法基本一致。

es6新提出了一种数据结构类型,叫做set数据结构,它和我们的数组类似,但是成员的值都是唯一的,没有重复的值。所以我们可以通过它来实现数组的去重。

                                        let str = ['r', 'j', 'l', 'r'];
                                        let strset = new Set(str);
                                        let laststr = [...strset];
                                        console.log(laststr);    

是不是很简单啊,哈哈哈哈。。。。。。

在这里还需要搞清楚一个原理,就是push()方法的工作原理。底下这个是将对象给其附上了数组的属性与方法,主要还是理解push的工作原理

 var obj = {
            '2': 3,
            '3': 4,
            'push': Array.prototype.push,
            'splice': Array.prototype.splice,
            'length': 2

        }
        obj.push(1);
        obj.push(2)
        console.log(obj);

这段代码告诉我们push的真正工作原理是这样的

	Array.prototype.push=function push(elem){
				this[this.length]=elem;
				this.length++;
				}

关于apply()方法和call()方法,他们两个其实区别不大,主要的不同就是后面传递参数时不一样,apply()方法后面传递的是数组,call()方法传递的是具体的参数。

至于bind方法,他会返回一个不会执行的函数,仍然改变了this的指向。传递参数和那个call是一样的,一下代码可以实现bind方法的功能

 var p = {
        name: 'renjialei'
    }
     function Person(age, sex) {
        console.log(this);
        console.log(this.name);
        console.log(age, sex);
    }
    Person.bind(p)();
    
    //实现一个bind方法!
    Function.prototype.bindy = function(context) {
        var _self = this;
        var args = Array.prototype.slice.call(arguments, 1);  //1代表从第二个位置开始截取

        return function() {
            var newargs = Array.prototype.slice.call(arguments);    

            _self.apply(context, args.concat(newargs));   //传入两个参数,context默认代表第一个参数
        }
    }
    Person.bindy(p, '18')('man');

在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理:

   var divs = document.getElementsByTagName("div");       
   var div = Array.prototype.slice.call(divs);

Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换),此时将具有数组的方法。

Object.prototype.toString.call()方法
在实际开发中tostring()方法确实被继承了下来,但被自己的儿子数组给重写了方法。所以在数组上直接调用该方法会返回一个字符串。

     var a = [];    
     console.log(Object.prototype.toString.call(a)); //[Object Array]
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值