在js中,所有的函数再被调用的时候都会默认传入两个参数,一个是this,还有一个是arguments。在默认情况下this都是指当前的调用函数的对象。但是有时候我们需要改变this的指向,也就是说使函数可以被其他对象来调用,那么我们应该怎样做呢?这时候我们就可以使用call,apply和bind方法了。
认为call 和 apply,bind 都是为了改变函数体内部 this 的指向。
看下面代码;
var name="小明",age=17;var perz={name:"小张",age:18,thename:this.name,theage:this.age,myatt:function(){console.log(this)console.log("名字:"+this.name+";年龄:"+this.age+";"+this.thename+this.theage);}}var li={name:"小李",age:19,thename:"小东",theage:16}var xm=perz;xm.myatt();perz.myatt.call(li); perz.myatt.apply(li); perz.myatt.bind(li)();
>{name: "小张", age: 18, thename: "小明", theage: 17, myatt: ƒ}
名字:小张;年龄:18;小明17 >{name: "小李", age: 19, thename: "小东", theage: 16} 名字:小李;年龄:19;小东16 >{name: "小李", age: 19, thename: "小东", theage: 16} 名字:小李;年龄:19;小东16 >{name: "小李", age: 19, thename: "小东", theage: 16} 名字:小李;年龄:19;小东16
bind绑定this;
var name="小明",age=17;var perz={name:"小张",age:18,thename:this.name,theage:this.age,myatt:(function(){console.log(this)console.log("名字:"+this.name+";年龄:"+this.age+";"+this.thename+this.theage);}).bind(this)//绑定this }var li={name:"小李",age:19,thename:"小东",theage:16}var xm=perz;xm.myatt();perz.myatt.call(li); perz.myatt.apply(li); perz.myatt.bind(li)();
>Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
名字:小明;年龄:17;undefinedundefined
>Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
名字:小明;年龄:17;undefinedundefined>Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
名字:小明;年龄:17;undefinedundefined>Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
名字:小明;年龄:17;undefinedundefined
传参
var name="小明",age=17;var perz={name:"小张",age:18,myatt:function(tall,weight){console.log("名字:"+this.name+";年龄:"+this.age+";"+"身高:"+tall+"体重:"+weight);}}var li={name:"小李",age:19,}var xm=perz;xm.myatt();perz.myatt.call(li,170,62); //传参perz.myatt.apply(li,[170,62]); perz.myatt.bind(li,170,62)();
名字:小张;年龄:18;身高:undefined体重:undefined
名字:小李;年龄:19;身高:170体重:62 名字:小李;年龄:19;身高:170体重:62 名字:小李;年龄:19;身高:170体重:62
call,apply和bind的异同
都是用来改变函数的this对象的指向的,
第一个参数都是this要指向的对象,
都可以利用后续参数传参
fun.call(thisArg, arg1, arg2, ...)
func.apply(thisArg, [argsArray])
function.bind(thisArg[, arg1[, arg2[, ...]]])
,bind 返回的是一个新的函数,你必须调用它才会被执行。
apply,call,bind实例
验证是否是数组(前提是toString()方法没有被重写过)
function isArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]' ;}
数组追加
var array = ['a', 'b'];var elements = [0, 1, 2];array.push.apply(array, elements);console.log(array)
>(5) ["a", "b", 0, 1, 2]
类数组对象转数组
var unboundSlice = Array.prototype.slice;var slice = Function.prototype.apply.bind(unboundSlice);arguments={0:23,1:'jojo',2:'pr',length:3};arr=slice(arguments);console.log(arr)
>(3) [23, "jojo", "pr"]