记录高级js学习(六)模拟this绑定方法以及类数组转数组

37 阅读1分钟

字符串,数值,布尔类型通用转对象类型方法 Object(123) Object("abc")

function(...arg){} 打印的arg为剩余参数,即传过来的所有参数形成的数组

js简单模拟一个call()

function foo(a,b){
        console.log(this);
        console.log('a: ', a);
        console.log('b: ', b);
}
Function.prototype.myCall = function(newThis,...arg){
        var fn = this  //this指向函数调用体
        //判断传的是否为null和undefined,均不是则把绑定的this强制转化为对象
        newThis = (newThis!=null && newThis!=undefined) ? Object(newThis) : window  
        newThis.foo = fn   //借用隐式绑定
        var result = newThis.foo(...arg)
        delete newThis.foo
        return result
}
foo.myCall("nihao",1,2)

js简单模拟一个apply()

Function.prototype.myApply = function(newThis,arg){
        var fn = this  
        newThis = (newThis!=null && newThis!=undefined) ? Object(newThis) : window  
        newThis.foo = fn   
        arg = arg ?? []    //多一个判断是否传了参数,不然下面的展开数组参数会报错
        var result = newThis.foo(...arg)
        delete newThis.foo
        return result
}
foo.myApply("nihao",[1,2])

js简单模拟一个bind()

Function.prototype.myBind = function(newThis,...arg){
        var fn = this  
        newThis = (newThis!=null && newThis!=undefined) ? Object(newThis) : window  
        newThis.foo = fn   
        return function(...otherArg){
          var result = newThis.foo(...arg,...otherArg)
          delete newThis.foo
          return result
        }
}
var bar = foo.myBind("nihao",1)
bar(2)

防止foo字段重复可以使用Symbol,这里就不实现了

函数内arguments会把所有传的参数组合成一个类数组(能通过索引遍历,但不具备数组的api方法),不管有没有接收,不过现在不推荐用了,可以用剩余参数替代。以下是将类数组转数组的方法:

  1. var newArr1 = for循环遍历push
  2. var newArr2 = Array.prototype.slice().call(arguments) //调数组方法改变this,模拟js如下代码
  3. var newArr3 = [].slice().call(arguments) //与2类似
  4. var newArr4 = Array.from(arguments) //ES6新特性
  5. var newArr5 = [...arguments] //展开运算法也可实现
Array.prototype.mySlice = function(start,end){
        var arr = this  
        start = start ?? 0
        end = end ?? this.length
        var newArr = []
        for(var i=start;i<end;i++){  //同方法1
          newArr.push(arr[i])
        }
        return newArr
}

箭头函数没有arguments 会从上级作用域找