javascript中apply,call,bind的个人理解

mac2022-06-30  9

apply的用法

使用如下:
将某对象obj执行func方法; //thisArg:在func运行时的this值,在非严格模式下使用null/undefined会自动替换为指向全局对象; //argsArray:数组或类数组对象 func.apply(thisArg,[agsArray]) 数组拼接(在前/后),改变原数组,返回数组长度,例如: let a=[2,3,4,1,0,9]; let b=[5,6,8]; a.push.apply(a,b); // a:[2,3,4,1,0,9,5,6,8] a.unshift.apply(a,b);//a:[5, 6, 8, 2, 3, 4, 1, 0, 9] 在一些需要数组中每个元素作为参数的内置函数中能简洁方便使用,例如Math.max/Max.min,在不使用apply时,数组长度很大时根本没法写,那么这时就可以使用: let testArray=[2,3,4,1,0,9]; Math.max.apply(null,testArray); Math.min.apply(null,testArray);

这里需要注意的是有时候调用的函数参数个数有限制(javascript核心中已经做了硬编码,限制参数个数为65536),而需要传入的数组个数又比较大,因此可以分段使用apply进行求值,例如求数组最小值:

function getArrayMin(arr){ let min=Infinity; let plusNum=32768; for(let i=0,len=arr.length;i<len;i+=plusNum){ let tempArr=arr.slice(i,Math.min((i+plusNum),len)); min=Math.min(min,Math.min.apply(null,tempArr)); } return min; }

call的用法

使用如下:
指定一个运行时的this值,和一个或多个参数调用函数func: //若call没有第一个参数,那么thisArgs默认被绑定为全局对象 //thisArgs为null/undefined时,this为window;thisArgs为String/Number/Boolean值时,this为new String()/new Number()/new Boolean() func.call(thisArgs,arg1,arg2,arg3,arg4,arg5...)

使用call 方法 指定this上下文,可为不同对象调用某个对象的方法:

objA.func.call(objB,arg1,arg2,...)

⚠️当不传入第一个参数时,默认this值表示全局对象,在严格模式下表示undefined。

使用call 提供不同的this值给调用的构造函数可使对象实现继承: function Product(name, price) { this.name = name; this.price = price; } function Food(name, price) { Product.call(this, name, price);//调用父构造函数实现继承 this.category = 'food'; } var food=new Food('chicken',15);//food已包含name,price

bind的用法

bind创建一个新函数即为原函数的拷贝,将this值调用新函数
使用如下:
使用语法如下: //当func没有参数时,arg...也没有 func.bind(thisArgs,arg1,arg2,arg3,arg4...)

用法跟call有点像,但是bind是返回原函数的拷贝并没有被执行,而call是直接执行了。

bind函数有预设参数时,在调用bind函数时优先传入预设参数 function list(arg1,arg2){ return arg1+arg2 } var listObj=list.bind(null,37); var listRes=listObj(5,4); // 37+5=42 第二个参数被忽略 当需要将对象的方法拿出时,单独调用时this往往易丢失,例如: var testFunc=document.write; testFunc('Hello!'); //报错,显示window/global对象没有testFunc方法

此时就可以用到bind:

var testFunc=document.write; testFunc.bind(document)('Hello!'); //或者 testFunc.bind(document,'Hello')(); testFunc.call(document,'Hello!'); 改变setTimeout调用func时的this指向。 默认情况下,window.setTimeout(func,seconds) 中在调用func时的this指向window/global对象,因此若想改变则可以使用bind: function LateBloomer() { this.petalCount = Math.ceil(Math.random() * 12) + 1; } // 在 1 秒钟后声明 bloom LateBloomer.prototype.bloom = function() { // 在bloom中的this指向LateBloomer对象 window.setTimeout(this.declare.bind(this), 1000); }; LateBloomer.prototype.declare = function() { console.log('I am a beautiful flower with ' + this.petalCount + ' petals!'); }; var flower = new LateBloomer(); flower.bloom(); // 一秒钟后, 调用'declare'方法 使用bind为对象实现继承:作为构造函数使用的bind函数: 效果和call差不多,需要多写一步调用: function Parent(x,y){ this.x=x; this.y=y; } var obj={}; var testObj=Parent.bind(obj); testObj(2,4); // obj:{x:2,y:4} var yAxisObj=Parent.bind(null,1,2); var axisObj=new yAxisObj(2,4); //axisObj:{x:1,y:2} 快捷调用:后面补充
最新回复(0)