proxy - handler.apply(target, object, args) method is used to intercept function calls

proxy - handler .apply(target, object, args) method is used to intercept function calls


Recently, because I am learning ES6, in addition to watching videos, I have read many excellent articles on the Internet and learned from them. I would like to use this article to record my understanding and usage of the interception of handler.apply(target, object, args) of the Proxy object. Partly because of the large space, I will write each interception method separately. This is the first time I write a blog. I hope and thank God for helping to correct it.

1. What is apply(target, object, args )?

The handler.apply() method is used to intercept function calls, as well as call, apply and bind operations, such as proxy(…args), proxy.call(object, …args), proxy.apply(…), proxy.bind(… )().

2. Grammar

var p =  new  Proxy ( target ,  { 
    //target-target object (function). 
    //thisArg-context object when called. 
    //argumentsList-arguments array when called 
  apply :  function ( target , thisArg , argumentsList )  { 
      /*code*/ 
  } 
} ) ;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Return Value : The apply method can return any value.

3. The following are two examples and my understanding of them after getting on the machine

Example 1

//apply(target, object, args) 
//Intercept function calls, as well as call, apply and bind operations, such as proxy(...args), proxy.call(object, ...args), proxy.apply( ...), proxy.bind(...)(). 
{ 
  function  foo ( a , b ) { 
    return a + b ; 
  } 
  //Intercept the call of the foo function and modify the actual return value of the foo function! 
  let proxy = new  Proxy ( foo , { 
      apply ( target , ctx , args ) { 
          // console.log(target+","+ctx,+","+args); 
          // console.log(ctx); 
          let num =1;
          for(let i=0;i<args.length;i++){
              // console.log(args[i]);
              num*=args[i];
          }
          //return target(...args);
          return num;
      }
  })
  console.log('proxy',proxy(10,20));//200
  let obj= { 
      a : 10 , 
      b : 30 
  } 
   //Intercept the call of the foo function and modify the actual return value of the foo function! 
  console . log ( 'obj-call' , proxy . call ( obj , 10 , 20 ) ) ;  // 200 ctx in apply is obj 
  console . log ( 'obj-apply' , proxy . apply ( obj , [ 20 , 20 , 30 ] ) ) ; // ctx in 12000 apply is obj 
  console . log ( 'window' , proxy . call ( window , 10 , 20 ) ) ;  // ctx in 200 apply is window 
  console . log ( proxy . call ( null , 30 , 20 ) ) ;  // ctx in 600 apply is null 
  console . log ( proxy . bind ( window , 20 ) ( 10) ) ;  // ctx in 200 apply is window 
  console . log ( proxy . toString ( 10 ) ) ; // will not be intercepted 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

Example 2

//handler.apply() method is used to intercept function calls. handler is an object 
//instance 
{ 
  //original function 
  function  sum ( a , b )  { 
    return a + b ; 
  }

  //Intercept the call to sum to customize the return value of the modified sum function 
  let handler =  { 
    apply ( target , thisArg , argumentsList )  { 
      // console.log(target); // f sum(a,b){return a+b;} 
      console . log ( `Calculate sum: ${ argumentsList } ` ) ; //Check if the function is called or not 
      // return target(argumentsList[0],argumentsList[1]) * 10; 
      return argumentsList [ 0 ]  * argumentsList [ 1 ] ; 
    } 
  } ;
  //Instantiate a proxy object 
  let proxy1 =  new  Proxy ( sum , handler ) ;

  //By printing the result, we can see whether apply() successfully intercepted 
  console . log ( 'sum' , sum ( 1 , 2 ) ) ;  //3 Because the original function was called directly, it was not intercepted 
  console . log ( proxy1 ( 1 , 2 ) ) ;  //30 It can be seen that it is intercepted by calling the proxy object
  
  let obj = {
    a:1,
    b:3,
  }

  console . log ( 'sum' , sum ( 1 , 2 ) ) ;  //3 not intercepted 
  console . log ( proxy1 ( 1 , 2 ) ) ;  //30 intercepted
  
  //A.call(B) A.apply(B) A.bind(B)() Change this point, if B object calls the method or property of A object, this will be transferred from A to B 
  //call 
  console . log ( 'proxy-call-obj' , proxy1 . call ( obj , 10 , 20 ) ) ;  //proxy-call 200 is intercepted (context object thisArg - obj when called) 
  console . log ( 'proxy-call-window ' , proxy1 . call ( window , 10 , 20 ) ) ;  //proxy-call-window 200 is intercepted (context object thisArg - window when called) 
  console .log ( 'proxy-call-null' , proxy1 . call ( null , 10 , 20 ) ) ;  //proxy-call-null 200 is intercepted (context object thisArg - null when called)

  //apply 
  console . log ( 'proxy-apply-obj' , proxy1 . apply ( obj , [ 30 , 40 ] ) ) ;  // proxy-apply-obj 1200 is intercepted (context object thisArg - obj when called) 
  console . log ( 'proxy-apply-window' , proxy1 . apply ( window , [ 30 , 40 ] ) ) ;  //proxy-apply-window 1200 is intercepted (context object thisArg - window when called) 
  console . log( 'proxy-apply-null' , proxy1 . apply ( null , [ 30 , 40 ] ) ) ;  //proxy-apply-null 1200 intercepted (context object thisArg - null when called)

  //bind 
  console . log ( 'proxy-bind-obj' , proxy1 . bind ( obj , 4 ) ( 5 ) ) ;  // proxy-bind-window 20 is intercepted (context object thisArg - obj when called) 
  console . log ( 'proxy-bind-obj' , proxy1 . bind ( window , 4 ) ( 5 ) ) ;  //proxy-bind-window 20 is intercepted (context object thisArg - window when called) 
  console . log ( ' proxy-bind-null', proxy1 . bind ( null , 4 ) ( 5 ) ) ;  //proxy-bind-null 20 intercepted (context object thisArg - null when called) 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

Note : A.call(B), A.apply(B), and A.bind(B)() all change the this point, which means that when the B object calls the method or property of the A object, this changes from A to B

Summary : The proxy object is actually the proxy object of the original object, as the proxy layer in the middle of data transmission. At this time, the role of handler.apply(target, object, args) is obviously visible, that is, when the outside wants to access the original object, if we want to protect The value returned by the original object can be intercepted by the proxy object, and the return value can be modified by itself in the handler.apply() method, which serves the purpose of protecting the original object.

Reference link:
Understanding proxy and its common usage
hanlder.app() - JavaScript | MDN

Related: proxy - handler.apply(target, object, args) method is used to intercept function calls