Friday, May 11, 2018

Setter and Getter compatability

The below is another way of setting and getting property values and its really a very compatible mode.

Simple Example :


1
2
3
4
5
6
7
8
function User(name, age) {
  this.name = name;
  this.age = age;
}

let john = new User("Test", 25);

alert( john.age ); // 25

Explanation:

1. Line no 6 we are creating value for name and age property.  So the name and age will be assigned  (setter).

2. In line no 8, we are getting age value.

Getter and Setter with Javascript Property

Below is the code how JS code getter and setter should be,


1
2
3
4
5
6
7
8
9
let obj = {
  get propName() {
    // getter, the code executed on getting obj.propName
  },

  set propName(value) {
    // setter, the code executed on setting obj.propName = value
  }
};

Line no 2 and 6 get and set is keyword and propName is your property name to set and get value.

Example:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
let user = {
  name: "FirstName",
  surname: "LastName",

  get fullName() {
    return `${this.name} ${this.surname}`;
  }
};

alert(user.fullName); // FirstName LastName

Explanation:

1. line no 1 user is an object which have name and surname property.

2. Through line no 10, when you call alert(user.fullName) control will be moved to line no 5 and it will be executed.

3. So line no 6 will return the result your user object property with the help of "this".

Example II:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
let user = {
  name: "First",
  surname: "Second",

  get fullName() {
    return `${this.name} ${this.surname}`;
  },

  set fullName(value) {
    [this.name, this.surname] = value.split(" ");
  }
};

// set fullName is executed with the given value.
user.fullName = "Third Fourth";

alert(user.name); //Third
alert(user.surname);// Fourth





Solution for losing this - Function binding

Top avoid losing of this , we can wrapping a function.

Example :

Solution I:
1
 2
 3
 4
 5
 6
 7
 8
 9
10
let user = {
  firstName: "TestName",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(function() {
  user.sayHi(); // Hello, TestName
}, 3000);

Now above code will work, since we have passed user.sayHi() as function (Outer lexical environment). So it will work like normal method call.

However, using arrow function (ES6) will short your code and solve this problem very easily without any confusing.

Example II: Arrow function :

Solution II:

1
2
3
4
5
6
7
8
let user = {
  firstName: "TestName",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(() => user.sayHi(), 3000);


Example III:

Solution III:
Using bind built in method

Before proceeding we must know its syntax.

let boundFunc = func.bind(context);


Below is the example code and its explanation is below. Now you can understand better.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
let user = {
  firstName: "TestName"
};

function func() {
  alert(this.firstName);
}

let funcUser = func.bind(user);
funcUser(); // TestName

From the above example, func method bind was done and assigned to funcUser. So calling the funcUser will provide the correct result. Means, this bind with user object.

Example IV:

Binding with Object method:



1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
let user = {
  firstName: "TestName",
  sayHi() {
    alert(`Hello, ${this.firstName}`);
  }
};

let sayHi = user.sayHi.bind(user); // (*)

sayHi(); // Hello, TestName

setTimeout(sayHi, 1000); // Hello, TestName






Losing this - Function binding


Actually, this is an old concept only because If you are using ES6 and you don not worry about this. To know more about function binding , check below.

Example Scenario :

Just assume that, you are using setTimeout with object methods or you are trying to passing object methods, then you will loss "this" power.

Means, using this.xxxxx something will give you the result as undefined.

Example code for losing "this":


1
2
3
4
5
6
7
8
let user = {
  firstName: "TestName",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(user.sayHi, 3000); // Hello, undefined!

Explanation:

1. We have set 3 seconds for setTimeout function at line no 8.

2. Now sayHi method will be executed and it try to print firstName with the help of this.firstName.

3. As "this" was lost , it will print undefined.






Wednesday, May 9, 2018

Difference between Call and Apply


1. The call method always expect comma separated parameters.

2. The apply method always expect array of arguments.

3. However, call and apply both expecting object as first parameter.

Note:

In ES6, we know spread operator ... and you can pass an array (or any iterable) as a list of arguments.

So using this spread with call, almost you are achieving apply concept.


1
2
3
4
let args = [1, 2, 3];

func.call(context, ...args); // pass an array as list with spread operator
func.apply(context, args);

From the above code you can find some minor difference, let see what is that

1. The spread operator ... is iterable args.

2. The apply accepts only array-like args.

So an iterate is possible with call and it works.  Whereas we expect an array-like, apply works.

Generally apply will be faster because of its single operation.

func.apply

Already we saw about call and its expecting comma separated parameters. But in apply we should pass array arguments.

A simple example,


1
2
3
4
5
6
7
8
9
function say(time, phrase) {
  alert(`[${time}] ${this.name}: ${phrase}`);
}

let user = { name: "John" };

let arrayData = ['10:00', 'Hello'];

say.apply(user, arrayData); 

Explanation :

1. We are using apply at line no 9. Here user is our context and arrayData is array arguments for this apply.

2. In the arrayData 10:00 will be considered as time and phrase will be considered as Hello.

3. After executing lie no 9 control moves to line 1 to execute a method say and will print the output.


func.call

Its a built-in function method func.call(context, …args) that allows to call a function explicitly by setting this.

The syntax is


func.call(context, arg1, arg2, ...)

A simple example is below,


1
2
3
4
5
6
7
function say(phrase) {
  alert(this.name + ': ' + phrase);
}

let user = { name: "JavaScript" };

say.call( user, "Hello" ); // Javascript: Hello

Explanation :

1. In line no 7, we have used user as our context and Hello as our argument.

2. You can pass multiple parameters like arg1, arg2 etc.,

3. After executing line no 7, control will move to line no 1 and say method will be executed.


Things to Remember :

Generally, most of the people will get ambiguous for call and apply. To remember this, use mnemonic is "A for array(apply) and C for comma (call).