ENGLISH:
The purpose of these notes is to become acquainted with three methods: call(), apply(), and bind().
The difference between 'call()' and 'apply()':
- 'call()' takes arguments separately
- 'apply()' takes arguments as an array
CODE:
// JS
// The Basics of JS Function Constructors aka Object Constructors (mostly from W3S)
function Person(first, last, age, eye) {
this.firstName = first
this.lastName = last
this.age = age
this.eyeColor = eye
}
const myFather = new Person('John', 'Doe', 50, 'blue') // myFather is storing what's called "a new instance of Person"
console.log(myFather) // Person {firstName: 'John', lastName: 'Doe', age: 50, eyeColor: 'blue'}
myFather.nationality = 'English'
console.log(myFather) // Person {firstName: 'John', lastName: 'Doe', age: 50, eyeColor: 'blue', nationality: 'English'}
myFather.fullName = function() {
return `${this.firstName} ${this.lastName}`
}
console.log(myFather) // Person {firstName: 'John', lastName: 'Doe', age: 50, eyeColor: 'blue', nationality: 'English', fullName: ƒ ()}
console.log(myFather.fullName) // ƒ () { return `${this.firstName} ${this.lastName}` }
console.log(myFather.fullName()) // John Doe
// Note that we can't add a new property to a constructor the same way we add a new property to an existing object.
// In other words, the following does not work: Person.nationality = 'English'
// To add a new property to a constructor, we must add the new property to the actual constructor function.
// Just FYI:
// Built-in JS constructors for native objects
// new String() // A new String object
// new Number() // A new Number object
// new Boolean() // A new Boolean object
// new Object() // A new Object object
// new Array() // A new Array object
// new RegExp() // A new RegExp object
// new Function() // A new Function object
// new Date() // A new Date object
//-------------------------------------------------------------------
// JS
// call() (mostly from MDN)
// The 'call()' method calls a function with a given 'this' value and arguments provided *individually*.
// Example 1
// 'call()' provides a new value of 'this' to the function/method (the 'Food' function in the below example).
// With 'call()', we can write a method once (the 'Product' function in the below example) and then inherit it in another object,
// without having to rewrite the method for the new object.
function Product(productName, productPrice) {
this.name = productName
this.price = `$${productPrice}`
}
console.log(new Product('chocolate', 3)) // Product {name: 'chocolate', price: '$3'}
function Food(foodName, foodPrice) {
Product.call(this, foodName, foodPrice)
this.category = 'food'
}
console.log(new Food('cheese', 5)) // Food {name: 'cheese', price: '$5', category: 'food'}
console.log(new Food('cheese', 5).name) // cheese
console.log(new Food('cheese', 5).price) // $5
console.log(new Food('cheese', 5).category) // food
// Example 2
function Product(productName, productPrice, productWeight) {
this.name = productName
this.price = `$${productPrice}`
this.weight = `${productWeight} lb.`
}
function Food(foodName, foodPrice, foodWeight) {
Product.call(this, foodName, foodPrice, foodWeight)
this.category = 'food'
}
console.log(new Food('cheese', 5, 2)) // Food {name: 'cheese', price: '$5', weight: '2 lb.', category: 'food'}
// Example 3
// We can use 'call()' to chain constructors for an object (similar to Java).
// In the following example, the constructor for the 'Product' object is defined with two parameters: 'productName' and 'productPrice'.
// Two other functions, 'Food' and 'Toy', *** invoke 'Product' ***, passing 'this', 'foodName'/'toyName', and 'foodPrice'/'toyPrice'.
// *** 'Product' initializes the properties 'name' and 'price'. ***
// Both specialized functions ('Food' and 'Toy') define the 'category'.
function Product(productName, productPrice) {
this.name = productName
this.price = `$${productPrice}`
}
function Food(foodName, foodPrice) {
Product.call(this, foodName, foodPrice)
this.category = 'food'
}
function Toy(toyName, toyPrice) {
Product.call(this, toyName, toyPrice)
this.category = 'toy'
}
const cheese = new Food('feta', 5)
const fun = new Toy('robot', 40)
console.log(cheese) // Food {name: 'feta', price: '$5', category: 'food'}
console.log(fun) // Toy {name: 'robot', price: '$40', category: 'toy'}
// Example 4
const person = {
fullName: function() {
return `${this.firstName} ${this.lastName}`
}
}
const person1 = {
firstName: 'John',
lastName: 'Doe'
}
const person2 = {
firstName: 'Jane',
lastName: 'Doe'
}
console.log(person.fullName.call(person1)) // John Doe
console.log(person.fullName.call(person2)) // Jane Doe
// Example 5
const person = {
fullName: function(city, country) {
return `${this.firstName} ${this.lastName} is from ${city}, ${country}`
}
}
const person1 = {
firstName: 'John',
lastName: 'Doe'
}
console.log(person.fullName.call(person1, 'Oslo', 'Norway')) // John Doe is from Oslo, Norway
// For other examples, like for using 'call()' to invoke an anonymous function, go here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
//-------------------------------------------------------------------
// JS
// apply() (mostly from MDN)
// The 'apply()' method calls a function with a given 'this' value, and 'arguments' provided *as an array (or an array-like object)*.
// Example 1
const numbers = [5, 6, 2, 3, 7]
const max = Math.max.apply(null, numbers)
console.log(max) // 7
const min = Math.min.apply(null, numbers)
console.log(min) // 2
// Note that when the first argument of 'apply()' is 'undefined' or 'null', as in the above example,
// a similar outcome can be achieved using the array 'spread' syntax:
const numbers = [5, 6, 2, 3, 7]
const max = Math.max(...numbers)
console.log(max) // 7
const min = Math.min(...numbers)
console.log(min) // 2
// Example 2
// 'push()' appends the whole 'array2' array to 'array'.
// 'concat()' appends the elements from 'array2' to a new array.
// 'apply()' appends the elements from 'array2' to 'array'.
// With 'push()'
const array = ['a', 'b']
const array2 = [0, 1, 2]
array.push(array2)
console.log(array) // ['a', 'b', [0, 1, 2]]
// With 'concat()'
const array = ['a', 'b']
const array2 = [0, 1, 2]
const newArr = array.concat(array2)
console.log(newArr) // ['a', 'b', 0, 1, 2]
// With 'apply()'
const array = ['a', 'b']
const array2 = [0, 1, 2]
array.push.apply(array, array2)
console.log(array) // ['a', 'b', 0, 1, 2]
// Example 3
// Note that this example is identical to Example 4 of 'call()', but with 'apply()' instead.
const person = {
fullName: function() {
return `${this.firstName} ${this.lastName}`
}
}
const person1 = {
firstName: 'John',
lastName: 'Doe'
}
const person2 = {
firstName: 'Jane',
lastName: 'Doe'
}
console.log(person.fullName.apply(person1)) // John Doe
console.log(person.fullName.apply(person2)) // Jane Doe
// Example 4
// Note that this example is identical to Example 5 of 'call()', except that:
// 'apply()' is used instead of 'call()' and 'apply()' accepts arguments in an *array*.
const person = {
fullName: function(city, country) {
return `${this.firstName} ${this.lastName} is from ${city}, ${country}`
}
}
const person1 = {
firstName: 'John',
lastName: 'Doe'
}
console.log(person.fullName.apply(person1, ['Oslo', 'Norway'])) // John Doe is from Oslo, Norway
// For other examples, like for using 'apply()' to chain constructors for an object, go here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
//-------------------------------------------------------------------
// JS
// bind() (mostly from MDN)
// The 'bind()' method creates a new function that, when called, has its 'this' keyword set to the provided value,
// with a given sequence of arguments preceding any provided when the new function is called.
// Example 1
// Creating a bound function
const module = {
x: 42,
getX: function() {
return this.x
}
}
console.log(module.getX()) // 42
const unboundGetX = module.getX
console.log(unboundGetX) // ƒ () { return this.x }
console.log(unboundGetX()) // undefined // the function gets invoked at the global scope
const boundGetX = unboundGetX.bind(module)
console.log(boundGetX()) // 42
// Example 2
// Creating a bound function, again
this.x = 9 // this 'this' refers to the global 'window' object
const module = {
x: 81,
getX: function() { return this.x }
}
console.log(module.getX()) // 81
const retrieveX = module.getX
console.log(retrieveX()) // 9 // the function gets invoked at the global scope
// Create a new function with 'this' bound to 'module'
const boundGetX = retrieveX.bind(module)
console.log(boundGetX()) // 81
// Example 3
// Partially applied functions (making a function with pre-specified initial arguments)
// These arguments (if any) follow the provided 'this' value and are then inserted at the start of the arguments
// passed to the target function, followed by whatever arguments are passed to the bound function at the time it
// is called.
function list() {
return Array.from(arguments)
}
function addArguments(arg1, arg2) {
return arg1 + arg2
}
const list1 = list(1, 2, 3)
console.log(list1) // [1, 2, 3]
const result1 = addArguments(1, 2)
console.log(result1) // 3
// Create a function with a preset leading argument
const leadingThirtysevenList = list.bind(null, 37)
// Create a function with a preset first argument.
const addThirtySeven = addArguments.bind(null, 37)
const list2 = leadingThirtysevenList()
console.log(list2) // [37]
const list3 = leadingThirtysevenList(1, 2, 3)
console.log(list3) // [37, 1, 2, 3]
const result2 = addThirtySeven(5)
console.log(result2) // 42 // from 37 + 5
const result3 = addThirtySeven(5, 10)
console.log(result3) // 42 // from 37 + 5 // the second argument is ignored
// For other examples, go here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Discussion (0)
Subscribe
For further actions, you may consider blocking this person and/or reporting abuse
Discussion (0)