Explain Context vs Scope in JavaScript
Answer: In JavaScript, "context" and "scope" are related but distinct concepts:
Scope: Scope refers to the visibility and accessibility of variables, functions, and objects in particular parts of your code during runtime. JavaScript has function-level scope by default, meaning variables defined inside a function are only accessible within that function (unless they're declared globally or passed as references). With ES6 and the introduction of 'let' and 'const', block-level scoping is also supported.
- Global Scope: Variables declared outside of any function or block have global scope and can be accessed throughout the entire script.
- Function Scope: Variables declared within a function have function scope and are only accessible within that function.
- Block Scope: Variables declared using 'let' or 'const' inside a block (denoted by '{}') are only accessible within that block.
Context: Context refers to the value of 'this' keyword which is a reference to the object that owns the current executing code. The context can change depending on how a function is called, and it is determined at runtime.
- Global Context: When 'this' is used outside of any function or object, it refers to the global object (in browsers, it refers to 'window' object).
- Function Context: Inside a function, 'this' refers to the object that calls the function (the "owner" of the function). This can be explicitly set using functions like 'call()', 'apply()', or 'bind()'.
Understanding scope helps you manage variable access and avoid naming conflicts, while understanding context is crucial for dealing with object-oriented programming and event handling in JavaScript. These concepts are fundamental for writing efficient and maintainable JavaScript code.
Explain call(), apply(), bind() by examples in JS.
Answer: In JavaScript, 'call()', 'apply()', and 'bind()' are methods used to manipulate how functions are executed and how 'this' is determined within them.
Here’s a breakdown of each with examples:
The 'call()' method calls a function with a given 'this' value and arguments provided individually.
Syntax:
functionName.call(thisArg, arg1, arg2, ...);
Example:
let person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + ", " + city + ", " + country;
}
};
let person1 = {
firstName: "John",
lastName: "Doe"
};
// Using call() to invoke fullName on person1
let result = person.fullName.call(person1, "Oslo", "Norway");
console.log(result); // Output: John Doe, Oslo, Norway
The 'apply()' method calls a function with a given 'this' value and arguments provided as an array or array-like object.
Syntax:
functionName.apply(thisArg, [argsArray]);
Example:
let person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + ", " + city + ", " + country;
}
};
let person1 = {
firstName: "John",
lastName: "Doe"
};
// Using apply() to invoke fullName on person1
let args = ["Oslo", "Norway"];
let result = person.fullName.apply(person1, args);
console.log(result); // Output: John Doe, Oslo, Norway
The 'bind()' method creates a new function that, when called, has its 'this' keyword set to a provided value, with a given sequence of arguments preceding any provided when the new function is called.
Syntax:
let newFunc = functionName.bind(thisArg, arg1, arg2, ...);
Example:
let person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + ", " + city + ", " + country;
}
};
let person1 = {
firstName: "John",
lastName: "Doe"
};
// Using bind() to create a new function with context and partial arguments
let fullNameOslo = person.fullName.bind(person1, "Oslo", "Norway");
// Now, fullNameOslo is a function that can be called separately
let result = fullNameOslo();
console.log(result); // Output: John Doe, Oslo, Norway
In brief:-
- 'call(thisArg, arg1, arg2, ...)': Calls a function with a specified 'this' value and arguments provided individually.
- 'apply(thisArg, [argsArray])': Calls a function with a specified 'this' value and arguments provided as an array or arraylike object.
- 'bind(thisArg, arg1, arg2, ...)': Creates a new function that, when called, has its 'this' keyword set to a provided value and can have arguments preset.
These methods are powerful for manipulating function context ('this') and parameter binding in JavaScript, especially in scenarios like method borrowing, partial application, or creating bound functions for event handlers.
Explain bind() and currying by example in JS?
Answer: In JavaScript, 'bind()' and currying are both techniques used to manipulate functions, often to control the context ('this' binding) and to pre-set arguments. Here’s an explanation of each with examples:The 'bind()' method creates a new function that, when called, has its 'this' keyword set to a provided value, with a given sequence of arguments preceding any provided when the new function is called.
Syntax:
let newFunc = functionName.bind(thisArg, arg1, arg2, ...);
Example:
// Example function
function greet(greeting, punctuation) {
return '${greeting}, ${this.name}${punctuation}';
}
let person = {
name: "John"
};
// Using bind() to create a new function with a specific context and preset arguments
let greetJohn = greet.bind(person, "Hello");
console.log(greetJohn("!")); // Output: Hello, John!
console.log(greetJohn(".")); // Output: Hello, John.
Explanation:
- - In this example, 'greet' is a function that takes two parameters: 'greeting' and 'punctuation'.
- - 'person' is an object with a 'name' property.
- - 'greet.bind(person, "Hello")' creates a new function 'greetJohn' where 'this' is bound to 'person', and the 'greeting' parameter is preset to '"Hello"'.
- - When 'greetJohn' is called with different punctuation ('"!"' and '"."'), it appends them to the preset greeting and 'this.name'.Currying is a functional programming technique where a function with multiple arguments is converted into a sequence of nested functions, each taking a single argument. It allows you to partially apply a function, creating new functions with some of the arguments already set.
function multiply(a, b, c) {
return a * b * c;
}
// Currying using a closure
function curryMultiply(a) {
return function(b) {
return function(c) {
return a * b * c;
};
};
}
// Using curried function
let multiplyByTwo = curryMultiply(2);
let multiplyByTwoAndThree = multiplyByTwo(3);
console.log(multiplyByTwoAndThree(4)); // Output: 24 (2 * 3 * 4)
Explanation:
- 'multiply' is a function that takes three arguments.
- 'curryMultiply' is a curried version of 'multiply'. It returns a function that takes one argument ('a'), which returns another function that takes one argument ('b'), which in turn returns a function that takes the final argument ('c').
- 'multiplyByTwo' is a function returned by 'curryMultiply(2)', which sets 'a' to '2'.
- 'multiplyByTwoAndThree' is a function returned by 'multiplyByTwo(3)', which sets 'b' to '3'.
- Finally, 'multiplyByTwoAndThree(4)' calls the innermost function with 'c' set to '4', resulting in '2 * 3 * 4 = 24'. 'bind()' is used to set the 'this' context and optionally preset some initial arguments of a function.
Both techniques are powerful in JavaScript for creating more flexible and reusable functions, enhancing code readability, and enabling functional programming paradigms.
No comments:
Post a Comment