js advanced call(),apply,bind().

call() function

The call() method is to replace the object saved by the default this attribute in the original function with a specified object. And corresponding functions can be provided.
		var obj ={
			name:'sean',
			age: 22
		}
		function foo(){
			console.log('name:'+this.name);
			console.log('age:'+this.age);
			
		}
		foo.call(obj);   // name:sean    age:22
  • Main points
  1. foo function executed
  2. Where this points to obj

Next, we will simulate the call function, which is implemented in three parts

The first part

  • First, how to implement this part? First, add this method to the object to be executed. Then the object has this function.
		var obj ={
			name:'sean',
			age: 22,
			foo:function(){
				console.log('name:'+this.name);
				console.log('age:'+this.age);
			}
		}
		obj.foo();  //name:sean    age:22
  • At this time, this refers to obj, which can be executed directly.
  • But there is another problem, that is, adding this method to the object, but originally my obj object does not contain this method, so at the end of execution, we should not forget to delete this method we added.
  • So the steps can be divided into:
    • Set the function to the property method of the executed object
    • Execute this function
    • Delete this method
      That is:
		obj.fun =foo;  //First step
		obj.fun();    //Step 2, execute
		delete obj.fun;   //Step 3, delete

Here, fun is an attribute name. It doesn't matter what the name is (as long as it doesn't conflict with the original object attribute, it doesn't matter in general. After all, it's simulation now. When it's really going to be developed, it's still using the native apply and call functions).

According to the above ideas, you can write the first version of the call function, named callBro();

		/* 
		 * Set the function to the property method of the executed object
		 * Execute this function
		 * Delete this method 
		 * 
		 * Parameter: context, passing in the object specified by this, function execution context.
		 */
		Function.prototype.callBro =function(context){
			//You can find the function object to be executed through this
			//Set as a property
			context.fun =this;
			//Execute this function;
			context.fun();
			//delete
			delete context.fun;
		};
		
		var obj ={
			name:'sean',
			age: 22
		}
		function foo(){
			console.log('name:'+this.name);
			console.log('age:'+this.age);
		}
		
		//Execution function
		foo.call(obj);   //name:sean   age:22

The second part

  • call can specify not only this object, but also parameters.
  • Here is how to solve the parameter problem
		var obj ={
			name:'sean',
			age:22
		}
		
		function foo(sex){
			console.log('sex:'+sex);
			console.log('name:'+this.name);
			console.log('age:'+this.age);
		}
		
		foo('male');   // sex:male  name:sean   age:22
  • Note: the parameters passed in are not sure. What can I do?
    We can do this by using a pseudo array of arguments.
    Take the second to last parameter and put it in an array.
    such as
// For example, the arguments at this time are:
// arguments = {
//      0: obj,
//      1: 'male', 
//      length: 2
// }
// Because arguments are class array objects, you can use the for loop

//Starting from 1
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
    args.push('arguments[' + i + ']');
}
// After execution, args are ["arguments[1]", "arguments[2]", "arguments[3]"]
  • The indefinite parameter problem has been solved, but how to put it into the executed function
  • context.fun(argus.join(','))
  • This method can't be used. What should be passed in is a string. It won't be parsed as a variable

So use this eval()

eval('context.fn(' + args +')')

Answer of the Second Edition: (overcome the problem of variable parameters)

		Function.prototype.callBro =function(context){
			//You can find the function object to be executed through this
			//Set as a property
			context.fun =this;
			
			//Create an array, save the. arguments class array in addition to the first object to traverse
			var args = [];
			for(var i = 1, len = arguments.length; i < len; i++) {
			    args.push('arguments[' + i + ']');
			}
			//Execute this function;
			//Here, args will automatically call Array.toString().
			//Equivalent to args.toString()
			eval('context.fun(' + args.toString() +')')
			//delete
			delete context.fun;
		};
		
		var obj ={
			name:'sean',
			age: 22
		}
		
		function foo(sex){
			console.log('sex:'+sex);
			console.log('name:'+this.name);
			console.log('age:'+this.age);
		}
		
		foo.callBro(obj,'male')// sex:male name:sean   age:22

The third part

Today is the first time to eat hotpot during the epidemic. I made it by myself. I'll eat it as soon as possible. I'll make it more later. O (O)

Published 14 original articles, won praise 2, visited 254
Private letter follow

Keywords: Attribute

Added by tinyashcities on Fri, 13 Mar 2020 06:20:36 +0200