Preface
call and apply exist to change the context in which a function runs, that is, to change the direction of this inside the function.
call and apply work exactly the same, but they accept parameters differently.
Method Definition
apply
The Function.apply(obj,args) method can take two parameters:
obj: This object will replace the this object in the Function class
args: This is an array or class array, and the apply method passes elements from this collection as parameters to the called function.
call
The call method is the same as the first parameter of the apply method, except that the second parameter is a list of parameters
In non-strict mode, when our first parameter is passed as null or undefined, this in the function body points to the default host object, while in the browser it is window
var test = function(){ console.log(this===window); } test.apply(null);//true test.call(undefined);//true
usage
"Hijacking" Other People's Ways
The logName method in foo is now referenced by bar, and this points to bar
var foo = { name:"mingming", logName:function(){ console.log(this.name); } } var bar={ name:"xiaowang" }; foo.logName.call(bar);//xiaowang
Implement Inheritance
function Animal(name){ this.name = name; this.showName =function(){ console.log(this.name); } } function Cat(name){ Animal.call(this, name); } var cat = new Cat("Black Cat"); cat.showName(); //Black Cat
In real-world development, we often encounter this pointing to scenes that were inadvertently changed.
There is a local fun method where this inside the fun points to window when it is called as a normal function, but we often want it to point to the #test node, as shown in the following code:
window.id="window"; document.querySelector('#test').onclick =function(){ console.log(this.id);//test varfun = function(){ console.log(this.id); } fun();//window }
With call,apply we can easily solve this problem
window.id="window"; document.querySelector('#test').onclick =function(){ console.log(this.id);//test varfun = function(){ console.log(this.id); } fun.call(this);//test }
You can, of course, do the same, but in the strict mode of ECMAscript 5, this is already defined as not pointing to global objects, but undefined:
window.id="window"; document.querySelector('#test').onclick =function(){ varthat = this; console.log(this.id);//test varfun = function(){ console.log(that.id); } fun();//test }
function func(){ "use strict" alert (this ); // Output: undefined } func();
Other uses
Class Array
Objects that meet the following criteria are called class arrays here
1. Has the length attribute
2. Store data indexed
3. push,pop, etc. without arrays
Common class arrays are arguments,NodeList!
(function(){ Array.prototype.push.call(arguments,4); console.log(arguments);//[1, 2, 3, 4] })(1,2,3)
So go to push 4 in arguments
The Array.prototype.push page combines two numbers
The push method also does not provide an array of push, but it does provide push(param1,param,...paramN) So you can also use apply to swap this array, that is:
var arr1=new Array("1","2","3"); var arr2=new Array("4","5","6"); Array.prototype.push.apply(arr1,arr2); console.log(arr1);//["1", "2", "3", "4", "5", "6"]
It is also understood that arr1 calls the push method, where parameters are assembled by apply and replaced by a collection of parameter lists.
For example, I want to find the maximum value in the class array
(function(){ varmaxNum = Math.max.apply(null,arguments); console.log(maxNum);//56 })(34,2,56);
Type of judgment
console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toString.call('123')) //[object String] console.log(Object.prototype.toString.call(undefined)) //[object Undefined] console.log(Object.prototype.toString.call(true)) //[object Boolean] console.log(Object.prototype.toString.call({})) //[object Object] console.log(Object.prototype.toString.call([])) //[object Array] console.log(Object.prototype.toString.call(function(){})) //[object Function]