Wednesday, January 9, 2019

Javascript: Destructuring

Destructuring Objects

With destructuring, you can extract multiple pieces of data at the same time via patterns in locations that receive data.

const person = {
   first: "John",
   last: "Doe",
   links: {
      social: {
         twitter: "https://twitter.com/john.ca",
         facebook: "https://facebook.com/johndoe"
      },
      web: {
         blog: "https://johndoe.com"
      }
   }
};

const { twitter, facebook } = person.links.social;

Rename the variables as you destructure
const { twitter: tweet, facebook: fb } = person.links.social;

Set fallback or default value
const settings = { width: 300, color: "black" };
const { width = 100, height = 100, color = "blue", fontSize = 25 } = settings;

Destructuring arrays

const details = ["John Doe", 123, "johndoe.com"];
const [name, id, website] = details;
console.log(name, id, website);

Destructuring comma separated string

const data = "Basketball,Sports,90210,23,John,Doe,cool";
const [itemName, category, sku, inventory] = data.split(",");

Destructuring into Rest - an example using rest parameter

const team = ["John", "Harry", "Sarah", "Keegan", "Riker"];
const [captain, assistant, ...players] = team;

Swapping Variables with Destructuring

let inRing = "Hulk Hogan";
let onSide = "The Rock";

[inRing, onSide] = [onSide, inRing];

To make order of arguments independent, wrap these 3 arguments in , and then pass an object in tipCalc function so that it destructures the object.

function tipCalc({ total = 100, tip = 0.15, tax = 0.13 }) {
   return total + tip * total + tax * total;
}

const bill = tipCalc({ tip: 0.2, total: 200 });
console.log(bill);

What is we don't pass anything in tipcalc?

function tipCalcDefault({ total = 100, tip = 0.15, tax = 0.13 } = {}) {
   return total + tip * total + tax * total;
}

const newBill = tipCalcDefault();
console.log(newBill);
Share This:    Facebook Twitter

Javascript: Spread and Rest Operators

Rest Operator

Takes multiple things and packs it into a single array

function convertCurrency(rate, ...amounts) {
   console.log(rate, amounts); // 1.5 [10, 20, 30]
}
convertCurrency(1.5, 10, 20, 30);

Can be used while destructuring into an array

const team = ["John", "Kait", "Lux", "Sheena", "Kelly"];
const [captain, assistant, ...players] = team;
console.log(captain, assistant, players);

Spread Operator

(3 dots in-front of an array or any iterable) Takes every single item from an iterable (that can loop over with for-of loop) and spread it into a new array

const featured = ["Deep Dish", "Pepperoni", "Hawaiian"];
const specialty = ["Meatzza", "Spicy Mama", "Margherita"];

const pizzas = [...featured, "veg", ...specialty];

Using above example, creating a new array fridayPizzas

const fridayPizzas = [...pizzas];

pizzas != fridayPizzas (shallow copy)

Spread string
const name = "john";
console.log([...name]); // ["j", "o", "h", "n"]

Remove an object from an array of objects
const comments = [
   { id: 209384, text: "I love your dog!" },
   { id: 523423, text: "Cuuute! 🐐" },
   { id: 632429, text: "You are so dumb" },
   { id: 192834, text: "Nice work on this wes!" }
];
const id = 632429;
const commentIndex = comments.findIndex(comment => comment.id === id);

const newComments = [
   ...comments.slice(0, commentIndex),
   ...comments.slice(commentIndex + 1)
];
console.log(newComments);

Spreading into a function
const inventors = ["Einstein", "Newton", "Galileo"];
const newInventors = ["Musk", "Jobs"];
inventors.push(...newInventors); // and not inventors.push(newInventors);
console.log(inventors);

One more example

const name = ["John", "Doe"];

function sayHi(first, last) {
   alert(`Hey there ${first} ${last}`);
}

sayHi(...name);
Share This:    Facebook Twitter

Saturday, January 5, 2019

Creating named credential with API key

1. Create a named credential like below specifying any username. Make sure that you have checked "Allow Merge Fields in HTTP Header" and unchecked "Generate Authorization Header" options.


2. Specify the API key in your Apex code using {!$Credential.Password} merge field.
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AnonAPI');
req.setHeader('APIKEY', '{!$Credential.Password}');
req.setMethod('GET');
HttpResponse res = new Http().send(req);

Share This:    Facebook Twitter

Friday, January 4, 2019

Javascript: Execution Context


Execution Context allows the Javascript engine to manage the complexity of interpreting and running the code. Every execution context has 2 phases: Creation phase and Execution phase.

The first execution context, the Global Execution Context, gets created when the Javascript engine runs your code. In this execution context,
  • Global object gets created, which is the window object.
  • this object gets created, pointing to the window object.
  • We set up memory space for variables and functions. 
  • All the variables declarations are assigned a default value of undefined (this is hoisting), while the function declaration is put entirely into memory.
In the execution phase, Javascript starts executing your code line by line.

Invoking a function creates the Function Execution Context. It is precisely the same as the global execution context except that instead of creating a global object, an arguments object gets created. Take, for example, the code below:
function fn() {
   console.log(arguments);
}

fn(x, y);

Here arguments is an array-like object for all of the arguments passing inside of this function, and a keyword in Javascript.

Now anytime a function is invoked, a new execution context is created and added to the execution stack. Whenever a function is finished running through both the creation phase and the execution phase, it gets popped off the execution stack.

Anytime you pass a variable to a function, that variable during the creation phase of a function execution context is going to be put in the variable environment of the current execution context as if they are local variables to the execution context. So for the code below
var name = 'John';
var handle = '@johndoe';

function getURL (handle) {
   var url = 'https://facebook.com/';
   return url + handle;
}

getURL(handle);

during the creation phase of getURL function, the value of url is undefined, while the value of handle is @johndoe as the variable is passed to a function. The value of arguments object during creation phase is {0:"@johndoe", length:1}.

If the Javascript engine can't find a variable local to the function's execution context, it will look to the nearest parent execution context for that variable. This process will continue all the way up until the engine reaches the global execution context. If the global execution context doesn't have the variable, then it will throw a reference error because that variable doesn't exist anywhere up to the scope chain or the execution context chain.

var name = 'John';

function logName() {
   console.log(name);
}

logName();

Now let's look at the code below:
var count = 0;

function makeAdder(x) {
   return function inner(y) {
      return x + y;
   };
}

var add5 = makeAdder(5);
count += add5(2);

Here we have a function nested inside a function (inner inside of makeAdder), and whenever that happens, the inner function is going to create a closure over the outer function's execution context. This is because later on when inner function is invoked, it needs to have access to any of the variables declared in the parent function's execution context even though that parent function's execution context has been removed from the stack. So the variables inside of this closure execution context are same as the variables that were in the makeAdder execution context. This whole concept is known as closure.
Share This:    Facebook Twitter

Monday, December 31, 2018

Rust: Ownership and Borrowing

The Stack and the Heap

Both the stack and the heap are parts of memory that are available to your code to use at runtime, but they are structured in different ways. The stack stores values in the order it gets them and removes the values in the opposite order. Adding data is called pushing onto the stack, and removing data is called popping off the stack.
All data stored on the stack must have a known, fixed size. Data with an unknown size at compile time or a size that might change must be stored on the heap instead. The heap is less organized: when you put data on the heap, you request a certain amount of space. The operating system finds an empty spot in the heap that is big enough, marks it as being in use, and returns a pointer, which is the address of that location. This process is called allocating on the heap. Because the pointer is a known, fixed size, you can store the pointer on the stack, but when you want the actual data, you must follow the pointer.
Accessing data in the heap is slower than accessing data on the stack because you have to follow a pointer to get there.
When your code calls a function, the values passed into the function (including, potentially, pointers to data on the heap) and the function’s local variables get pushed onto the stack. When the function is over, those values get popped off the stack.

Ownership Rules

  1. Each value in Rust has a variable that’s called its owner.
  2. There can be only one owner at a time.
  3. When the owner goes out of scope, the value will be dropped.
In the case of a string literal, we know the contents at compile time, so the text is hardcoded directly into the final executable. This is why string literals are fast and efficient. But these properties only come from the string literal’s immutability.

let s = "hello";

With the String type, in order to support a mutable, growable piece of text, we need to allocate an amount of memory on the heap, unknown at compile time, to hold the contents. This means:

  • The memory must be requested from the operating system at runtime. This is done when we call String::from.
  • We need a way of returning this memory to the operating system when we’re done with our String. In Rust, the memory is automatically returned once the variable that owns it goes out of scope. A scope is the range within a program for which an item is valid. The variable is valid from the point at which it’s declared until the end of the current scope.

    {
       let mut s = String::from("hello");
       s.push_str(", world!");
       println!("{}", s);
    };

    When a variable goes out of scope, Rust calls a special function for us. This function is called drop, and it’s where the author of String can put the code to return the memory. Rust calls drop automatically at the closing curly bracket.

Multiple variables interacting with the same data

Let’s look at this example:
let s1 = String::from("hello");
let s2 = s1;
println!("{}, world!", s1);   // Error

A String is made up of three parts, shown as below: a pointer to the memory that holds the contents of the string, a length, and a capacity. This group of data is stored on the stack. On the right is the memory on the heap that holds the contents.
When we assign s1 to s2, the String data is copied, meaning we copy the pointer, the length, and the capacity that are on the stack. We do not copy the data on the heap that the pointer refers to. In other words, the data representation in memory looks like below:
The above figure shows both data pointers pointing to the same location. This is a problem: when s2 and s1 go out of scope, they will both try to free the same memory. Freeing memory twice can lead to memory corruption, which can potentially lead to security vulnerabilities. To ensure memory safety, instead of trying to copy the allocated memory, Rust considers s1 to no longer be valid and, therefore, Rust doesn’t need to free anything when s1 goes out of scope. This is known as a move. In this example, we would say that s1 ptr was moved into s2.

Let’s look at this valid code, which seems to contradict what we just learned.
let x = 5;
let y = x;
println!("x = {}, y = {}", x, y);

The reason is that types such as integers that have a known size at compile time are stored entirely on the stack, so copies of the actual values are quick to make. Rust has a special annotation called the Copy trait that we can place on types like integers that are stored on the stack. If a type has the Copy trait, an older variable is still usable after assignment. Rust won’t let us annotate a type with the Copy trait if the type, or any of its parts, has implemented the Drop trait. Any group of simple scalar values can be Copy, and nothing that requires allocation or is some form of resource is Copy.

References and Borrowing

fn main() {
   let s1 = String::from("hello"); 
   let len = calculate_length(&s1); 
   println!("The length of '{}' is {}.", s1, len); 
} 

fn calculate_length(s: &String) -> usize {
   s.len() 
}

In the above example, we are passing &s1 into calculate_length and, in its definition, we take &String rather than String. These ampersands are references, and they allow you to refer to some value (s1) without taking ownership of it. Because it does not own it, the value it points to will not be dropped when the reference goes out of scope. Likewise, the signature of the function uses & to indicate that the type of the parameter s is a reference. When functions have references as parameters instead of the actual values, we don’t need to return the values in order to give back ownership, because we never had ownership.

We call having references as function parameters borrowing. As in real life, if a person owns something, you can borrow it from them. When you’re done, you have to give it back.



Share This:    Facebook Twitter

Total Pageviews

My Social Profiles

View Sonal's profile on LinkedIn

Tags

__proto__ $Browser Access Grants Accessor properties Admin Ajax AllowsCallouts Apex Apex Map Apex Sharing AssignmentRuleHeader AsyncApexJob Asynchronous Auth Provider AWS Callbacks Connected app constructor Cookie CPU Time CSP Trusted Sites CSS Custom settings CustomLabels Data properties Database.Batchable Database.BatchableContext Database.query Describe Result Destructuring Dynamic Apex Dynamic SOQL Einstein Analytics enqueueJob Enterprise Territory Management Enumeration escapeSingleQuotes featured Flows geolocation getGlobalDescribe getOrgDefaults() getPicklistValues getRecordTypeId() getRecordTypeInfosByName() getURLParameters Google Maps Governor Limits hasOwnProperty() Heap Heap Size IIFE Immediately Invoked Function Expression Interview questions isCustom() Javascript Javascript Array jsForce Lightning Lightning Components Lightning Events lightning-record-edit-form lightning:combobox lightning:icon lightning:input lightning:select LockerService Lookup LWC Manual Sharing Map Modal Module Pattern Named Credentials NodeJS OAuth Object.freeze() Object.keys() Object.preventExtensions() Object.seal() Organization Wide Defaults Override PDF Reader Performance performance.now() Permission Sets Picklist Platform events Popup Postman Primitive Types Profiles Promise propertyIsEnumerable() prototype Query Selectivity Queueable Record types Reference Types Regex Regular Expressions Relationships Rest API Rest Operator Revealing Module Pattern Role Hierarchy Salesforce Salesforce Security Schema.DescribeFieldResult Schema.DescribeSObjectResult Schema.PicklistEntry Schema.SObjectField Schema.SObjectType Security Service Components Shadow DOM Sharing Sharing Rules Singleton Slots SOAP API SOAP Web Services SOQL SOQL injection Spread Operator Star Rating stripInaccessible svg svgIcon Synchronous this Token Triggers uiObjectInfoApi Upload Files VSCode Web Services XHR
Scroll To Top