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)functionPerson(first,last,age,eye){this.firstName=firstthis.lastName=lastthis.age=agethis.eyeColor=eye}constmyFather=newPerson('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.functionProduct(productName,productPrice){this.name=productNamethis.price=`$${productPrice}`}console.log(newProduct('chocolate',3))// Product {name: 'chocolate', price: '$3'}functionFood(foodName,foodPrice){Product.call(this,foodName,foodPrice)this.category='food'}console.log(newFood('cheese',5))// Food {name: 'cheese', price: '$5', category: 'food'}console.log(newFood('cheese',5).name)// cheeseconsole.log(newFood('cheese',5).price)// $5console.log(newFood('cheese',5).category)// food// Example 2functionProduct(productName,productPrice,productWeight){this.name=productNamethis.price=`$${productPrice}`this.weight=`${productWeight} lb.`}functionFood(foodName,foodPrice,foodWeight){Product.call(this,foodName,foodPrice,foodWeight)this.category='food'}console.log(newFood('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'.functionProduct(productName,productPrice){this.name=productNamethis.price=`$${productPrice}`}functionFood(foodName,foodPrice){Product.call(this,foodName,foodPrice)this.category='food'}functionToy(toyName,toyPrice){Product.call(this,toyName,toyPrice)this.category='toy'}constcheese=newFood('feta',5)constfun=newToy('robot',40)console.log(cheese)// Food {name: 'feta', price: '$5', category: 'food'}console.log(fun)// Toy {name: 'robot', price: '$40', category: 'toy'}// Example 4constperson={fullName:function(){return`${this.firstName}${this.lastName}`}}constperson1={firstName:'John',lastName:'Doe'}constperson2={firstName:'Jane',lastName:'Doe'}console.log(person.fullName.call(person1))// John Doeconsole.log(person.fullName.call(person2))// Jane Doe// Example 5constperson={fullName:function(city,country){return`${this.firstName}${this.lastName} is from ${city}, ${country}`}}constperson1={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 1constnumbers=[5,6,2,3,7]constmax=Math.max.apply(null,numbers)console.log(max)// 7constmin=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:constnumbers=[5,6,2,3,7]constmax=Math.max(...numbers)console.log(max)// 7constmin=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()'constarray=['a','b']constarray2=[0,1,2]array.push(array2)console.log(array)// ['a', 'b', [0, 1, 2]]// With 'concat()'constarray=['a','b']constarray2=[0,1,2]constnewArr=array.concat(array2)console.log(newArr)// ['a', 'b', 0, 1, 2]// With 'apply()'constarray=['a','b']constarray2=[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.constperson={fullName:function(){return`${this.firstName}${this.lastName}`}}constperson1={firstName:'John',lastName:'Doe'}constperson2={firstName:'Jane',lastName:'Doe'}console.log(person.fullName.apply(person1))// John Doeconsole.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*.constperson={fullName:function(city,country){return`${this.firstName}${this.lastName} is from ${city}, ${country}`}}constperson1={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 functionconstmodule={x:42,getX:function(){returnthis.x}}console.log(module.getX())// 42constunboundGetX=module.getXconsole.log(unboundGetX)// ƒ () { return this.x }console.log(unboundGetX())// undefined // the function gets invoked at the global scopeconstboundGetX=unboundGetX.bind(module)console.log(boundGetX())// 42// Example 2// Creating a bound function, againthis.x=9// this 'this' refers to the global 'window' objectconstmodule={x:81,getX:function(){returnthis.x}}console.log(module.getX())// 81constretrieveX=module.getXconsole.log(retrieveX())// 9 // the function gets invoked at the global scope// Create a new function with 'this' bound to 'module'constboundGetX=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.functionlist(){returnArray.from(arguments)}functionaddArguments(arg1,arg2){returnarg1+arg2}constlist1=list(1,2,3)console.log(list1)// [1, 2, 3]constresult1=addArguments(1,2)console.log(result1)// 3// Create a function with a preset leading argumentconstleadingThirtysevenList=list.bind(null,37)// Create a function with a preset first argument.constaddThirtySeven=addArguments.bind(null,37)constlist2=leadingThirtysevenList()console.log(list2)// [37]constlist3=leadingThirtysevenList(1,2,3)console.log(list3)// [37, 1, 2, 3]constresult2=addThirtySeven(5)console.log(result2)// 42 // from 37 + 5constresult3=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
Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.
So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀
Top comments (0)