What is the difference between the ‘in’ operator and the ‘object.hasownProperty’ method?

HasOwnPropert method

The hasOwnPropert() method returns a Boolean value indicating whether the object has a specified property in its own properties, so this method ignores properties inherited from the stereotype chain.

Look at the following example:

Object.prototype.phone= '15345025546'; Let obj = {name: 'obj ', age: '28' } console.log(obj.hasOwnProperty('phone')) // false console.log(obj.hasOwnProperty('name')) // trueCopy the code

As you can see, if you define a variable phone on the function prototype, the hasOwnProperty method simply ignores it.

The in operator.

The IN operator returns true if the specified property is in the specified object or its stereotype chain.

Again, use the above example to illustrate:

console.log('phone' in obj) // true
Copy the code

You can see that the IN operator checks whether it or its stereotype chain contains an attribute with the specified name.

What are the methods for handling asynchronous code in JS?

  • The callback
  • Promise
  • async/await
  • There are also some libraries: async.js, Bluebird, Q, CO

What is the difference between a function expression and a function declaration?

Look at the following example:

hoistedFunc(); notHoistedFunc(); Function hoistedFunc(){console.log(" Note: I will be promoted "); } var notHoistedFunc = function(){console.log(" note: I am not promoted "); }Copy the code

NotHoistedFunc call raises an exception: Uncaught TypeError: NotHoistedFunc is not a function, and hoistedFunc calls do not, because hoistedFunc is promoted to the top of the scope, and notHoistedFunc is not.

What methods can be used to call a function?

There are four ways to call a function in JS.

Call as a function – If a function is not called as a method, constructor, apply, call, this points to the window object (non-strict mode)

//Global Scope function add(a,b){ console.log(this); return a + b; } the add (1, 5); // Prints the "window" object and 6 const o = {method(callback){callback(); } } o.method(function (){ console.log(this); // Print the "window" object});Copy the code

Call as a method – If an object’s property has a function value, we call it a method. When the method is called, the method’s this value points to the object.

const details = {
  name : "Marko",
  getName(){
    return this.name;
  }
}

details.getName(); // Marko
Copy the code

Call as constructor – If a function is called before it with the new keyword, the function is called a constructor. The constructor creates an empty object by default and points this to it.

Function Employee(name, position, yearHired) {// Create an empty object {} // then assign the empty object to the "this" keyword // this = {}; this.name = name; this.position = position; this.yearHired = yearHired; // If return is not specified, this} is returned by default; const emp = new Employee("Marko Polo", "Software Developer", 2017);Copy the code

Use the apply and call method calls – if we want to explicitly specify the this value of a function, we can use these methods, which are available to all functions.

const obj1 = { result:0 }; const obj2 = { result:0 }; function reduceAdd(){ let result = 0; for(let i = 0, len = arguments.length; i < len; i++){ result += arguments[i]; } this.result = result; } reduceAdd.apply(obj1, [1, 2, 3, 4, 5]); // The this object in the reduceAdd function will be obj1 ReduceAdd. call(obj2, 1, 2, 3, 4, 5); // The this object in the reduceAdd function will be obj2Copy the code

What is caching and what does it do?

Caching is the process of building a function that remembers the result or value of a previous calculation. The caching function is used to avoid the evaluation of a function that was executed in the last evaluation that used the same argument. This saves time, but the downside is that we will consume more memory to save previous results.

Manual implementation of caching methods]

function memoize(fn) {
  const cache = {};
  return function (param) {
    if (cache[param]) {
      console.log('cached');
      return cache[param];
    } else {
      let result = fn(param);
      cache[param] = result;
      console.log(`not cached`);
      return result;
    }
  }
}

const toUpper = (str ="")=> str.toUpperCase();

const toUpperMemoized = memoize(toUpper);

toUpperMemoized("abcdef");
toUpperMemoized("abcdef");
Copy the code

This cache function is used to take an argument. We need to change it to take more than one parameter.

const slice = Array.prototype.slice; function memoize(fn) { const cache = {}; return (... args) => { const params = slice.call(args); console.log(params); if (cache[params]) { console.log('cached'); return cache[params]; } else { let result = fn(... args); cache[params] = result; console.log(`not cached`); return result; } } } const makeFullName = (fName, lName) => `${fName} ${lName}`; const reduceAdd = (numbers, startingValue = 0) => numbers.reduce((total, cur) => total + cur, startingValue); const memoizedMakeFullName = memoize(makeFullName); const memoizedReduceAdd = memoize(reduceAdd); memoizedMakeFullName("Marko", "Polo"); memoizedMakeFullName("Marko", "Polo"); memoizedReduceAdd([1, 2, 3, 4, 5], 5); memoizedReduceAdd([1, 2, 3, 4, 5], 5);Copy the code

Why does Typeof NULL return Object? How do I check if a value is null?

Typeof NULL == ‘object’ always returns true, since this is the implementation of NULL since the creation of JS. There was an offer to change typeof NULL == ‘object’ to typeof NULL == ‘null’, but this was rejected as it would cause more bugs.

We can use the strict equality operator === to check if the value is null.

function isNull(value){
  return value === null;
}
Copy the code

What does the new keyword do?

The new keyword is used with the constructor to create an object:

function Employee(name, position, yearHired) {
  this.name = name;
  this.position = position;
  this.yearHired = yearHired;
};

const emp = new Employee("Marko Polo", "Software Developer", 2017);
Copy the code

The new keyword does four things:

  • Creating an empty object{}
  • Assigns an empty object tothis
  • Empty object**proto**Object pointing to the constructorprototype
  • If you don’t use explicitreturnStatement, returnsthis

Look at the following examples:

Function Person() {this.name = ‘this.name’}

According to the description above, new Person() does:

  • Create an empty object: var obj = {}

  • Assign an empty object to this: this = obj

  • Prototype: ‘this.__proto** = Person().prototype

  • Return this: return this

Simulate a new?

function objectFactory() { var obj = new Object(), Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; var ret = Constructor.apply(obj, arguments); Return typeof ret === 'object'? Return typeof ret === 'object'? ret : obj; };Copy the code

When not to use arrow functions? Name three or more examples?

Arrow functions should not be used in some cases:

  • When desired functions are promoted (arrow functions are anonymous)
  • You want to use it in a functionthis/argumentsBecause the arrow function itself does not havethis/argumentsSo they depend on the external context
  • Use named functions (arrow functions are anonymous)
  • When using a function as a constructor (arrow function has no constructor)
  • When we want to add functions as properties to object literals and use objects in them, because we can’t access themthisThe object itself.

What is the difference between object.freeze () and const? ]

Const and Object.freeze are two completely different concepts.

Const declares a read-only variable. Once declared, the value of the constant is immutable:

const person = {
    name: "Leonardo"
};
let animal = {
    species: "snake"
};
person = animal; // ERROR "person" is read-only    
Copy the code

Object.freeze applies to values, and more specifically to Object values, which make the Object immutable, that is, unable to change its properties.

let person = {
    name: "Leonardo"
};
let animal = {
    species: "snake"
};
Object.freeze(person);
person.name = "Lima"; //TypeError: Cannot assign to read only property 'name' of object
console.log(person); 
Copy the code

How to “deep freeze” an object in JS?

If we want to ensure that the object is deeply frozen, we must create a recursive function to freeze each attribute of the object type:

No deep freeze

let person = {
    name: "Leonardo",
    profession: {
        name: "developer"
    }
};
Object.freeze(person); 
person.profession.name = "doctor";
console.log(person); //output { name: 'Leonardo', profession: { name: 'doctor' } }
Copy the code

Deep freeze

function deepFreeze(object) {
    let propNames = Object.getOwnPropertyNames(object);
    for (let name of propNames) {
        let value = object[name];
        object[name] = value && typeof value === "object" ?
            deepFreeze(value) : value;
    }
    return Object.freeze(object);
}
let person = {
    name: "Leonardo",
    profession: {
        name: "developer"
    }
};
deepFreeze(person);
person.profession.name = "doctor"; // TypeError: Cannot assign to read only property 'name' of object
Copy the code

What is an Iterator and what does it do?

An Iterator is one such mechanism. It is an interface that provides a unified access mechanism for various data structures. The Iterator interface can be deployed on any data structure to complete traversal (that is, processing all members of the data structure in turn).

Iterator does three things:

  1. To provide a unified and simple access interface for various data structures;
  2. To enable the members of a data structure to be arranged in some order;
  3. ES6 creates a new traversal commandThe for... ofThe Iterator interface is mainly used forThe for... ofConsumption.

Traversal process:

  1. Creates a pointer object that points to the start of the current data structure. That is, the traverser object is essentially a pointer object.
  2. The first call to the next method of a pointer object points to the first member of the data structure.
  3. The next call to the next method of the pointer object points to the second member of the data structure.
  4. Call the next method of the pointer object until it points to the end of the data structure.

Each time the next method is called, information about the current member of the data structure is returned. Specifically, it returns an object containing both the value and done attributes. Where, the value attribute is the value of the current member, and the done attribute is a Boolean value indicating whether the traversal is complete.

//obj is iterable because it follows the Iterator standard and contains [symbol. Iterator] methods. The function also conforms to the standard Iterator interface specification. //obj.[Symbol. Iterator]() let obj = {data: [ 'hello', 'world' ], [Symbol.iterator]() { const self = this; let index = 0; return { next() { if (index < self.data.length) { return { value: self.data[index++], done: false }; } else { return { value: undefined, done: true }; }}}; }};Copy the code

What is the function ‘Generator’ and what does it do?

If JavaScrip is a concrete implementation of the ECMAScript standard and Iterator Iterator is a concrete implementation of Iterator, then Generator functions are a concrete implementation of the Iterator interface.

Execution of a Generator returns an iterator object. Each yield in a Generator is equivalent to the next() method of the iterator object, and the behavior of the Generator function can be changed by passing in a custom value through the next(value) method.

Generator functions can be combined with Thunk functions for asynchronous programming and control flow management with ease and elegance.