Karim Aya

Karim Aya

1565333085

Metaprogramming: An Introduction to JavaScript(ES6) Proxy

Originally published by Tapas Adhikary at blog.greenroots.info

Before we go any further, let us understand, What is Metaprogramming?

Metaprogramming

Metaprogramming is nothing less than a Magic! Truly, how about writing a program to Read, Modify, Analyze and even to Generate a Program? Doesn't it sound Wizardry and Powerful?

Wikipedia defines Metaprogramming as,

Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data.

So basically, it is the Program that deals with the Meta Data of another program and able to do lot of useful things.

Meet Proxy

Proxy wraps objects and intercepts their behavior through traps

Among several ways we can do Metaprogramming in JavaScript, usage of Proxyobject is one of the important one. Proxy object is an ES6 concept used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).

Here are few useful terms you need to remember and use:

  • target: an Object which the proxy virtualizes.
  • handler: a Placeholder Object which contains traps.
  • trap: the Methods that provide property access of the target object.

It is perfectly fine, if you haven't got much from the description above. We will understand it very easily through code and examples.

Code Time

Here is the syntax for creating a Proxy Object:

let p = new Proxy(target, handler); 

Now let us take an example of an employee object and try to print some of the properties of it:

const employee = {
    firstName: 'Tapas',
    lastName: 'Adhikary'
};
 
console.group('employee');
    console.log(employee.firstName);
    console.log(employee.lastName);
    console.log(employee.org);
    console.log(employee.fullName);
console.groupEnd()

Well, we know the expected output would be,

employee
  Tapas
  Adhikary
  undefined
  undefined

Now let us use the Proxy object to alter this program of employee handling and provide some behavior to it:

  • Step 1: Create a Handler that uses a Trap

We will be using a trap called get which is a trap for getting a property value. Here is our Handler:

let handler = {
    get: function(target, fieldName) {       
 
        if(fieldName === 'fullName' ) {
            return `${target.firstName} ${target.lastName}`;
        }
 
        return fieldName in target ?
            target[fieldName] :
                `No such property as, '${fieldName}'!`
 
    }
};

The above handler helps to create the value for fullName property. It also adds a better error message in case, we are dealing with a missing property.

  • Step 2: Create a Proxy Object

As we have the target as employee object and the handler, we will be able to create a Proxy object as:

let p = new Proxy(employee, handler);
  • Step 3: Access the properties on the Proxy object


console.group('proxy');
    console.log(p.firstName);
    console.log(p.lastName);
    console.log(p.org);
    console.log(p.fullName);
console.groupEnd()

You should be seeing the output as,

proxy
  Tapas
  Adhikary
  No such property as, 'org'!
  Tapas Adhikary

Notice how we have magically changed things for the employee object.

In Previous example, we used a trap called get. Here are the list of available traps:

  • apply
  • construct
  • defineProperty
  • deleteProperty
  • get
  • getOwnPropertyDescriptor
  • getPrototypeOf
  • has
  • isExtensible
  • ownKeys
  • preventExtensions
  • set
  • setPrototypeOf

More on these can be found here, Proxy - JavaScript | MDN

Proxy for Validation of Values

Let's create a handler(we can name it as, validator):

const validator = {
    set: function(obj, prop, value) {
        if (prop === 'age') {
            if(!Number.isInteger(value)) {
                throw new TypeError('Age is always an Integer, Please Correct it!');
            }
            if(value < 0) {
                throw new TypeError('This is insane, a negative age?');
            }
        }
    }
};

Again, we can create a Proxy object as:

let p = new Proxy(employee, validator); 

If you do,

p.age = 'I am testing the blunder'; 

The output would be a TypeError as,

TypeError: Age is always an Integer, Please Correct it!
    at Object.set (E:\Projects\KOSS\metaprogramming\js-mtprog\proxy\userSetProxy.js:28:23)
    at Object.<anonymous> (E:\Projects\KOSS\metaprogramming\js-mtprog\proxy\userSetProxy.js:40:7)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

Similarly, try doing this!

p.age = -1;

Use-cases

Proxy Object is a very powerful concept. There are several use-cases where this concept can be used. Here are few:

  • Protect ID field from deletion from an Object(trap: deleteProperty)
  • Tracing Property Accesses(trap: get, set)
  • Data Binding(trap: set)
  • Revocable references
  • Manipulate the in operator behavior

... and many many more.

Last Note

Hope you liked the concept of Proxy Object. Try it out, it is Fun! Feel free to access the examples from My Github Repo.

'Proxy' is not the only concept for JavaScript based Metaprogramming, there are are others like, Reflect. That is coming soon.

Originally published by Tapas Adhikary at blog.greenroots.info

===========================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

☞ Svelte.js - The Complete Guide

☞ The Complete JavaScript Course 2019: Build Real Projects!

☞ Become a JavaScript developer - Learn (React, Node,Angular)

☞ JavaScript: Understanding the Weird Parts

☞ JavaScript: Coding Challenges Bootcamp - 2019

☞ The Complete Node.js Developer Course (3rd Edition)

☞ Angular & NodeJS - The MEAN Stack Guide

☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

☞ Node.js Absolute Beginners Guide - Learn Node From Scratch

#javascript #es6 #web-development

What is GEEK

Buddha Community

Metaprogramming: An Introduction to JavaScript(ES6) Proxy

Great…i really love that

Tanya  Shields

Tanya Shields

1590596591

Metaprogramming: An Introduction to JavaScript(ES6) Proxy

The concept of Metaprogramming is not new. There are many programming languages like, Lisp, Scala, Clojure, Rust, Haskell, etc already got the use of it. JavaScript is not really behind either!

Before we go any further, let us understand, What is Metaprogramming?

Metaprogramming is nothing less than a Magic! Truly, how about writing a program to Read, Modify, Analyze and even to Generate a Program? Doesn’t it sound Wizardry and Powerful?
Wikipedia defines Metaprogramming as,

Metaprogramming is a programming technique in which computer programs have the ability to treat 
other programs as their data.

#javascript #web development #proxy #es6 #meta programming

Tanya  Shields

Tanya Shields

1597658520

Introduction to “Proxy” API for Metaprogramming in JavaScript

In the earlier lesson, we learned about some metaprogramming concepts one of which is intercession. Intercession stands for intervening in an operation or intercepting an operation. For example, if you trying to get the value of an object’s property, but that operation was intercepted by some JavaScript program and a false or modified value was returned instead.

Intercession is like a man-in-the-middle attack where data is transformed in-flight between the source and the consumer but done deliberately. The program that sits between the source and the consumer is called Proxy.

You may have heard about this term while connecting to a remote server through a proxy server that sits between you and the remote server. Here the proxy server is able to hide your identity from the remote server as well as transform data received from the remote server if necessary.

JavaScript gives us the [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) class in ES2015+ that helps us create a proxy around an object. The Proxy global object is a constructor function (class) and its constructor signature is as follows.

var proxy = new Proxy(target, handler);

Here, the target is the object for which a proxy needs to be created. The proxy is the object that will be used to perform some operations on the target. For example, proxy.prop = 1 operation would be handled by the handler and its job is to set the value of target.prop to 1.

💡 Both target and handler objects are required and must be descendents of Object and not a primitive value (including null and undefined). Else, TypeError: Cannot create proxy with a non-object as target or handler error is thrown.

Creating a proxy around target doesn’t prevent one from accessing the target but it should be kept private. The handler object contains specific methods one of which will be invoked by JavaScript when a certain operation is performed on the proxy and that method would be responsible to communicate with the target.

In the Reflect lesson, we learned about the internal slots and internal methods. Every proxy object has two internal slots viz. [[ProxyTarget]] and [[ProxyHandler]]. When we create a proxy object with new Proxy(), these slots are filled with target and handler arguments respectively.

Image for post

(source: ECMAScript 2015 Table 5)

In the Reflect lesson, we also learned about the essential internal methods of all objects and saw a table full of internal methods (table above). These internal methods are trigged by Reflect’s static methods. Guess what, a proxy object also has these exact same internal methods as shown in the table below. These method signatures are as same as the above table.

#ecmascript2015 #es6 #proxy #javascript #ecmascript #programming

Introduction With Basic JavaScript

The world’s most misunderstood programming language is JavaScript but JavaScript is now used by an incredible number of high-profile applications. So, it’s an important skill for any web or mobile developer to enrich the deeper knowledge in it.

Unlike most programming languages, the JavaScript language has no concept of input or output. It is designed to run as a scripting language in a host environment, and it is up to the host environment to provide mechanisms for communicating with the outside world.

Its syntax is based on the Java and C languages — many structures from those languages apply to JavaScript as well. JavaScript supports object-oriented programming with object prototypes, instead of classes. JavaScript also supports functional programming — because they are objects, functions may be stored in variables and passed around like any other object.

Let’s start off by looking at the building blocks of any language: the types. JavaScript programs manipulate values, and those values all belong to a type. JavaScript’s types are:

· Number

· String

· Boolean

· Function

· Object

· Symbol

and undefined and null, which are … slightly odd. And Array, which is a special kind of object. Date and RegExp, which are objects that you get for free. And to be technically accurate, functions are just a special type of object. So the type of diagram looks like this:

#beginner-javascript #javascript #javascript-introduction #javascript-fundamental #basic-javascritp

Karim Aya

Karim Aya

1565333085

Metaprogramming: An Introduction to JavaScript(ES6) Proxy

Originally published by Tapas Adhikary at blog.greenroots.info

Before we go any further, let us understand, What is Metaprogramming?

Metaprogramming

Metaprogramming is nothing less than a Magic! Truly, how about writing a program to Read, Modify, Analyze and even to Generate a Program? Doesn't it sound Wizardry and Powerful?

Wikipedia defines Metaprogramming as,

Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data.

So basically, it is the Program that deals with the Meta Data of another program and able to do lot of useful things.

Meet Proxy

Proxy wraps objects and intercepts their behavior through traps

Among several ways we can do Metaprogramming in JavaScript, usage of Proxyobject is one of the important one. Proxy object is an ES6 concept used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).

Here are few useful terms you need to remember and use:

  • target: an Object which the proxy virtualizes.
  • handler: a Placeholder Object which contains traps.
  • trap: the Methods that provide property access of the target object.

It is perfectly fine, if you haven't got much from the description above. We will understand it very easily through code and examples.

Code Time

Here is the syntax for creating a Proxy Object:

let p = new Proxy(target, handler); 

Now let us take an example of an employee object and try to print some of the properties of it:

const employee = {
    firstName: 'Tapas',
    lastName: 'Adhikary'
};
 
console.group('employee');
    console.log(employee.firstName);
    console.log(employee.lastName);
    console.log(employee.org);
    console.log(employee.fullName);
console.groupEnd()

Well, we know the expected output would be,

employee
  Tapas
  Adhikary
  undefined
  undefined

Now let us use the Proxy object to alter this program of employee handling and provide some behavior to it:

  • Step 1: Create a Handler that uses a Trap

We will be using a trap called get which is a trap for getting a property value. Here is our Handler:

let handler = {
    get: function(target, fieldName) {       
 
        if(fieldName === 'fullName' ) {
            return `${target.firstName} ${target.lastName}`;
        }
 
        return fieldName in target ?
            target[fieldName] :
                `No such property as, '${fieldName}'!`
 
    }
};

The above handler helps to create the value for fullName property. It also adds a better error message in case, we are dealing with a missing property.

  • Step 2: Create a Proxy Object

As we have the target as employee object and the handler, we will be able to create a Proxy object as:

let p = new Proxy(employee, handler);
  • Step 3: Access the properties on the Proxy object


console.group('proxy');
    console.log(p.firstName);
    console.log(p.lastName);
    console.log(p.org);
    console.log(p.fullName);
console.groupEnd()

You should be seeing the output as,

proxy
  Tapas
  Adhikary
  No such property as, 'org'!
  Tapas Adhikary

Notice how we have magically changed things for the employee object.

In Previous example, we used a trap called get. Here are the list of available traps:

  • apply
  • construct
  • defineProperty
  • deleteProperty
  • get
  • getOwnPropertyDescriptor
  • getPrototypeOf
  • has
  • isExtensible
  • ownKeys
  • preventExtensions
  • set
  • setPrototypeOf

More on these can be found here, Proxy - JavaScript | MDN

Proxy for Validation of Values

Let's create a handler(we can name it as, validator):

const validator = {
    set: function(obj, prop, value) {
        if (prop === 'age') {
            if(!Number.isInteger(value)) {
                throw new TypeError('Age is always an Integer, Please Correct it!');
            }
            if(value < 0) {
                throw new TypeError('This is insane, a negative age?');
            }
        }
    }
};

Again, we can create a Proxy object as:

let p = new Proxy(employee, validator); 

If you do,

p.age = 'I am testing the blunder'; 

The output would be a TypeError as,

TypeError: Age is always an Integer, Please Correct it!
    at Object.set (E:\Projects\KOSS\metaprogramming\js-mtprog\proxy\userSetProxy.js:28:23)
    at Object.<anonymous> (E:\Projects\KOSS\metaprogramming\js-mtprog\proxy\userSetProxy.js:40:7)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

Similarly, try doing this!

p.age = -1;

Use-cases

Proxy Object is a very powerful concept. There are several use-cases where this concept can be used. Here are few:

  • Protect ID field from deletion from an Object(trap: deleteProperty)
  • Tracing Property Accesses(trap: get, set)
  • Data Binding(trap: set)
  • Revocable references
  • Manipulate the in operator behavior

... and many many more.

Last Note

Hope you liked the concept of Proxy Object. Try it out, it is Fun! Feel free to access the examples from My Github Repo.

'Proxy' is not the only concept for JavaScript based Metaprogramming, there are are others like, Reflect. That is coming soon.

Originally published by Tapas Adhikary at blog.greenroots.info

===========================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

☞ Svelte.js - The Complete Guide

☞ The Complete JavaScript Course 2019: Build Real Projects!

☞ Become a JavaScript developer - Learn (React, Node,Angular)

☞ JavaScript: Understanding the Weird Parts

☞ JavaScript: Coding Challenges Bootcamp - 2019

☞ The Complete Node.js Developer Course (3rd Edition)

☞ Angular & NodeJS - The MEAN Stack Guide

☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

☞ Node.js Absolute Beginners Guide - Learn Node From Scratch

#javascript #es6 #web-development

Macey  Kling

Macey Kling

1598089920

Introduction to “Reflect” API for Metaprogramming in JavaScript

As we learned from the earlier lessonreflection represents introspectionintercession, and modification of the program. Prior to ES2015 (ES6), we had a few tools available to us to introspect and modify the behavior of the program such as Object.keys or instanceof operator among many.

In ES2015, we received a [Reflect](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) global object that provides some pretty useful methods for metaprogramming. Like [Math](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math) and [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) objects, Reflect is not a function nor it’s constructible. Its only job is to provide static methods for reflection. These methods can be divided into two categories.

Introspection methods are non-destructive methods. They are only used to introspect objects. Modification methods are destructive since they mutate the object or its behavior. Most of these methods are derived from old JavaScript implementations and we will talk about this as well.

In the earlier lesson, we took a quick look at the [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) class which is used to intercept object operations. Proxy handler methods and Reflect static methods share the same function signature. We will talk more about this in the Proxy lesson (coming soon) but let’s discuss briefly why these method signatures are the same. For that, we need to look inside ECMAScript specifications.

Object Internal Methods and Internal Slots

The 6.1.7.2 section of the ECMAScript 2015 specification talks about some weird internal properties and internal methods objects (_descendants of __Object_) can have. These properties or methods are implemented by the JavaScript engine but they are abstracted away from the runtime, hence you won’t be able to access them on the objects like normal properties.

These are represented by the [[<name>]] notation in the ECMAScript specification where name is the name of the internal property or internal method. The internal property is called an internal slot and it contains a value associated with that object to represent some state of the object.

Let’s take a quick example. The [[GetPrototypeOf]] internal method is implemented by all the objects and its job is to return the prototype of the object. When you execute Reflect.getPrototypeOf(_obj_) method with obj being the object whose prototype needs to be inspected, JavaScript engine calls the [[GetPrototypeOf]] internal method of the obj which returns the value of [[Prototype]] internal slot of the object that contains the prototype.

💡 The _obj.__proto___ also points to the prototype of the _obj_ and accessing it would be like accessing the _[[Prototype]]_ internal slot of the _obj_.

When an internal method is invoked on an object such as obj in the above example, it is called the “target” of the invocation. If the target doesn’t support an internal method, for example calling the Reflect.getPrototypeOf on null, a TypeError exception is thrown.

Objects can have multiple internal slots and internal methods. ECMAScript specification does not describe how these internal methods are implemented but it describes the signature of the method call. The following are ES2015 internal methods implemented by all objects (hence essential). These internal methods may accept some arguments of specific ECMAScript language types and may return a value

#es6 #ecmascript-6 #metaprogramming #javascript #ecmascript