Classes and Objects Flashcards

1
Q

When to use prototypes?

A

For instance, when creating a new object/class, methods should normally be associated to the object’s prototype rather than defined into the object constructor. The reason is that whenever the constructor is called, the methods would get reassigned (that is, for every object creation).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How to delete a property in an object?

A

delete object.propertyName

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is computed properties?

A
We can use square brackets in an object literal. That’s calledcomputed properties.
let fruit = prompt("Which fruit to buy?", "apple");
let bag = {
  [fruit]: 5, // the name of the property is taken from the variable fruit
};
alert( bag.apple ); // 5 if fruit="apple"
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Can we use reserved word for object properties?

A
yes. 
let obj = {
  for: 1,
  let: 2,
  return: 3
};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How would we know if a property exists in the object?

A

two ways: 1) checking if the value is undefined:

obj. prop === undefined
2) using in => prop in object // would return true or false

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

How can you loop through the properties of the object?

A
We can use a for in loop. 
let user = {
  name: "John",
  age: 30,
  isAdmin: true
};
for (let key in user) {
  // keys
  alert( key );  // name, age, isAdmin
  // values for the keys
  alert( user[key] ); // John, 30, true
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How are properties ordered in an object?

A

If the properties are numbers, they are sorted ascending and if not numbers, they are displayed in the order of creation.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

When we assign an object to another variable, are the whole object added or the reference?

A

The reference to the object is assigned to the new variable. So now both variables point to the same object and if any of the variables change any properties, it would be seen in the other variable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Does the equality operator == vary from the strict equality operator === when comparing objects?

A

When both variables are pointing to the same object the equality and strict equality operator act the same. But if there are 2 different objects, then the equality and strict equality differs.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

If we create a const object, can we add properties to it?

A
Yes, since the variable is only keeping the reference to the object and we can add properties to the object. If we wanted to assign it to another object, then it would give an error. 
const user = { name: 'Pete'}
user = { name: 'John'} => error
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How can we clone an object?

A

1) we can loop through the object keys and assign the same values to the same keys in the second object
2) we can use the Object.assign(dest, object1,object2, …, objectN); let user2 = Object.assign({}, user1);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How is garbage collected in JS?

A

It is being done automatically. and the main reason for it is Reachability.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is the basic garbage collector name and how does it work?

A

The basic garbage collection algorithm is called “mark-and-sweep”.

The following “garbage collection” steps are regularly performed:

The garbage collector takes roots and “marks” (remembers) them.
Then it visits and “marks” all references from them.
Then it visits marked objects and marks their references. All visited objects are remembered, so as not to visit the same object twice in the future.
…And so on until every reachable (from the roots) references are visited.
All objects except marked ones are removed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What types can the property name be in objects?

A

Property names are either strings or symbols.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is a symbol?

A

A “symbol” represents a unique identifier.

A value of this type can be created using Symbol():

// id is a new symbol
let id = Symbol();
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Do Symbols automatically convert to strings?

A

No, we either have to call toString() on it or we use the description:
let id = Symbol(‘id’);
id.toString() or id.description

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

What’s the benefit of usingSymbol(“id”)over a string”id” as object properties?

A

Asuserobjects belongs to another code, and that code also works with them, we shouldn’t just add any fields to it. That’s unsafe. But a symbol cannot be accessed accidentally, the third-party code probably won’t even see it, so it’s probably all right to do.
Also, imagine that another script wants to have its own identifier insideuser, for its own purposes. That may be another JavaScript library, so that the scripts are completely unaware of each other.
Then that script can create its ownSymbol(“id”), like this:
// …
let id = Symbol(“id”);
user[id] = “Their id value”;
There will be no conflict between our and their identifiers, because symbols are always different, even if they have the same name.
…But if we used a string”id”instead of a symbol for the same purpose, then therewouldbe a conflict:
let user = { name: “John” };
// Our script uses “id” property
user.id = “Our id value”;
// …Another script also wants “id” for its purposes…
user.id = “Their id value”
// Boom! overwritten by another script!

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

How can we add symbols to objects?

A
Once we create a symbol: let id = Symbol('id');
we can then add it to the object by placing it in square brackets: 
let user = { name: 'Joe', [id]: 123};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Would we see the symbol properties in objects while looping through the properties?

A

No, they will be skipped when using for in, the object.keys would also skip it. but we can directly access it. alert( “Direct: “ + user[id] );

20
Q

IF we clone another object that has string and symbol properties, would the symbol properties be also copied?

A

Yes

21
Q

Say we want same-named symbols to be same entities. For instance, different parts of our application want to access symbol”id”meaning exactly the same property. How can we do that?

A

To achieve that, there exists aglobal symbol registry. We can create symbols in it and access them later, and it guarantees that repeated accesses by the same name return exactly the same symbol.
In order to read (create if absent) a symbol from the registry, useSymbol.for(key).
That call checks the global registry, and if there’s a symbol described askey, then returns it, otherwise creates a new symbolSymbol(key)and stores it in the registry by the givenkey.

22
Q

What does Symbol.keyFor do?

A
For global symbols, not onlySymbol.for(key)returns a symbol by name, but there’s a reverse call:Symbol.keyFor(sym), that does the reverse: returns a name by a global symbol.
let sym2 = Symbol.for("id"); 
alert( Symbol.keyFor(sym2) ); // id

If the symbol is not global, it won’t be able to find it and returnsundefined.

23
Q

Is Symbol a primitive type or reference type?

A

Symbolis a primitive type for unique identifiers.

24
Q

What are the uses of symbols?

A
  1. “Hidden” object properties. If we want to add a property into an object that “belongs” to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear infor..in, so it won’t be accidentally processed together with other properties. Also it won’t be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite.
    So we can “covertly” hide something into objects that we need, but others should not see, using symbolic properties.
  2. There are many system symbols used by JavaScript which are accessible asSymbol.*. We can use them to alter some built-in behaviors. For instance, later in the tutorial we’ll useSymbol.iteratorforiterables,Symbol.toPrimitiveto setupobject-to-primitive conversionand so on.
25
Q

How can you access symbols in the object?

A

There is a built-in methodObject.getOwnPropertySymbols(obj)that allows us to get all symbols. Also there is a method namedReflect.ownKeys(obj)that returnsallkeys of an object including symbolic ones. So they are not really 100% hidden.

26
Q

Do arrow functions have ‘this’?

A

No, Arrow functions are special: they don’t have their “own”this. If we referencethisfrom such a function, it’s taken from the outer “normal” function.
For instance, herearrow()usesthisfrom the outeruser.sayHi()method:
let user = {
firstName: “Ilya”,
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
}
};
user.sayHi(); // Ilya

27
Q

let obj, method;

obj = {
go: function() { alert(this); }
};

(obj.go)(); // what does this line do?

A

It would return [object Object]

brackets do not change the order of operations here, the dot is first anyway.

28
Q

let obj, method;

obj = {
go: function() { alert(this); }
};

(method = obj.go)(); // (3) undefined

(obj.go || obj.stop)(); // (4) undefined

Why do lines 3 and 4 return undefined ?

A

Here we have a more complex call (expression).method(). The call works as if it were split into two lines:

f = obj.go; // calculate the expression
f();        // call what we have
Here f() is executed as a function, without this.

The similar thing as (3), to the left of the dot . we have an expression.

To explain the behavior of (3) and (4) we need to recall that property accessors (dot or square brackets) return a value of the Reference Type.

Any operation on it except a method call (like assignment = or ||) turns it into an ordinary value, which does not carry the information allowing to set this.

29
Q

Using “this” in object literal
importance: 5
Here the function makeUser returns an object.

What is the result of accessing its ref? Why?

function makeUser() {
  return {
    name: "John",
    ref: this
  };
};

let user = makeUser();

alert( user.ref.name ); // What’s the result?

A

Answer: an error.

Try it:

function makeUser() {
  return {
    name: "John",
    ref: this
  };
};

let user = makeUser();

alert( user.ref.name ); // Error: Cannot read property ‘name’ of undefined
That’s because rules that set this do not look at object definition. Only the moment of call matters.

Here the value of this inside makeUser() is undefined, because it is called as a function, not as a method with “dot” syntax.

The value of this is one for the whole function, code blocks and object literals do not affect it.

So ref: this actually takes current this of the function.

We can rewrite the function and return the same this with undefined value:

function makeUser(){
  return this; // this time there's no object literal
}

alert( makeUser().name ); // Error: Cannot read property ‘name’ of undefined
As you can see the result of alert( makeUser().name ) is the same as the result of alert( user.ref.name ) from the previous example.

Here’s the opposite case:
function makeUser() {
  return {
    name: "John",
    ref() {
      return this;
    }
  };
};

let user = makeUser();

alert( user.ref().name ); // John
Now it works, because user.ref() is a method. And the value of this is set to the object before dot ..

30
Q

How to convert objects to primitive values?

A

All objects are true in a boolean context. There are only numeric and string conversions.
The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, Date objects (to be covered in the chapter Date and time) can be subtracted, and the result of date1 - date2 is the time difference between two dates.
As for the string conversion – it usually happens when we output an object like alert(obj) and in similar contexts.

31
Q

There are three variants of type conversion, so-called “hints”, for converting objects to primitive values. What are they?

A
  • String
    // output
    alert(obj);
// using object as a property key
anotherObj[obj] = 123;
- NUMBER
// explicit conversion
let num = Number(obj);
// maths (except binary plus)
let n = +obj; // unary plus
let delta = date1 - date2;
  • DEFAULT
    Occurs in rare cases when the operator is “not sure” what type to expect.

For instance, binary plus + can work both with strings (concatenates them) and numbers (adds them), so both strings and numbers would do. So if the a binary plus gets an object as an argument, it uses the “default” hint to convert it.

Also, if an object is compared using == with a string, number or a symbol, it’s also unclear which conversion should be done, so the “default” hint is used.

// binary plus uses the "default" hint
let total = obj1 + obj2;
// obj == number uses the "default" hint
if (user == 1) { ... };
The greater and less comparison operators, such as < >, can work with both strings and numbers too. Still, they use the "number" hint, not "default". That’s for historical reasons.
32
Q

Do we have Boolean hint for converting obj to primitives?

A

No “boolean” hint
Please note – there are only three hints. It’s that simple.

There is no “boolean” hint (all objects are true in boolean context) or anything else. And if we treat “default” and “number” the same, like most built-ins do, then there are only two conversions.

33
Q

What are the three object methods for converting it to primitive values?

A

Call objSymbol.toPrimitive – the method with the symbolic key Symbol.toPrimitive (system symbol), if such method exists,
Otherwise if hint is “string”
try obj.toString() and obj.valueOf(), whatever exists.
Otherwise if hint is “number” or “default”
try obj.valueOf() and obj.toString(), whatever exists.

34
Q

Can you provide an example of the Symbol.toPrimitive type conversion?

A

let user = {

name: “John”,
money: 1000,

  [Symbol.toPrimitive](hint) {
    alert(`hint: ${hint}`);
    return hint == "string" ? `{name: "${this.name}"}` : this.money;
  }
};
// conversions demo:
alert(user); // hint: string -> {name: "John"}
alert(+user); // hint: number -> 1000
alert(user + 500); // hint: default -> 1500
35
Q

Can you provide an example of object to toString/valueOf type conversion?

A

If there’s no Symbol.toPrimitive then JavaScript tries to find them and try in the order:

toString -> valueOf for “string” hint.
valueOf -> toString otherwise.
These methods must return a primitive value. If toString or valueOf returns an object, then it’s ignored (same as if there were no method).

By default, a plain object has following toString and valueOf methods:

The toString method returns a string “[object Object]”.
The valueOf method returns the object itself.
Here’s the demo:

let user = {name: “John”};

alert(user); // [object Object]
alert(user.valueOf() === user); // true

let user = {

name: “John”,
money: 1000,

  // for hint="string"
  toString() {
    return `{name: "${this.name}"}`;
  },
  // for hint="number" or "default"
  valueOf() {
    return this.money;
  }

};

alert(user); // toString -> {name: “John”}
alert(+user); // valueOf -> 1000
alert(user + 500); // valueOf -> 1500

36
Q

What are function constructors?

A

When you want to create multiple objects, we can use the function constructor and we can create objects using the new keyword.

37
Q

Give an example of function constructor.

A

Constructor functions technically are regular functions. There are two conventions though:

They are named with capital letter first.
They should be executed only with “new” operator.
For instance:
function User(name) {
this.name = name;
this.isAdmin = false;
}

let user = new User(“Jack”);

alert(user.name); // Jack
alert(user.isAdmin); // false

When a function is executed with new, it does the following steps:

A new empty object is created and assigned to this.
The function body executes. Usually it modifies this, adds new properties to it.
The value of this is returned.

38
Q

If we have many lines of code all about creation of a single complex object, what should we do?

A

we can wrap them in constructor function, like this:

let user = new function() {

this. name = “John”;
this. isAdmin = false;

  // ...other code for user creation
  // maybe complex logic and statements
  // local variables etc
};
The constructor can’t be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
39
Q

What can the constructor function return?

A

Generally it returns this( the current object), but we can also return a new object. If we return primitives it will be ignored and the current object would be returned.
If return is called with an object, then the object is returned instead of this.
If return is called with a primitive, it’s ignored.
In other words, return with an object returns that object, in all other cases this is returned.

For instance, here return overrides this by returning an object:

function BigUser() {

this.name = “John”;

return { name: “Godzilla” }; //

40
Q

When can we omit the parenthesis when declaring a new object using the function constructor?

A

By the way, we can omit parentheses after new, if it has no arguments:

let user = new User; //

41
Q

How can we define methods in function contructors?

A
The functions we declare must be regular functions in order to use this object properties.
function User(name) {
  this.name = name;

this.sayHi = function() {
alert( “My name is: “ + this.name );
};
}

let john = new User(“John”);

john.sayHi(); // My name is: John

/*
john = {
   name: "John",
   sayHi: function() { ... }
}
*/
42
Q

Is it possible to create functions A and B such as new A()==new B()?

function A() { ... }
function B() { ... }
let a = new A;
let b = new B;

alert( a == b ); // true
If it is, then provide an example of their code.

A

Yes, it’s possible.

If a function returns an object then new returns it instead of this.

So they can, for instance, return the same externally defined object obj:

let obj = {};

function A() { return obj; }
function B() { return obj; }

alert( new A() == new B() ); // true

43
Q

What are object wrappers?

A

Object wrappers allow you to use the primitives as objects and to use their methods.
The “object wrappers” are different for each primitive type and are called: String, Number, Boolean and Symbol. Thus, they provide different sets of methods.

44
Q
What are the output of these two?
alert( typeof 0 ); 
alert( typeof new Number(0) );
A

1) alert( typeof 0 ); // “number”

2) alert( typeof new Number(0) ); // “object”!

45
Q

Do null and undefined have object wrappers?

A

No. The special primitives null and undefined are exceptions. They have no corresponding “wrapper objects” and provide no methods. In a sense, they are “the most primitive”.

An attempt to access a property of such value would give the error:

alert(null.test); // error

46
Q

Can I add a string property?
importance: 5
Consider the following code:

let str = “Hello”;

str.test = 5;

alert(str.test);
How do you think, will it work? What will be shown?

A

Try running it:

let str = “Hello”;

str.test = 5; // (*)

alert(str.test);
Depending on whether you have use strict or not, the result may be:

undefined (no strict mode)
An error (strict mode).
Why? Let’s replay what’s happening at line (*):

When a property of str is accessed, a “wrapper object” is created.
In strict mode, writing into it is an error.
Otherwise, the operation with the property is carried on, the object gets the test property, but after that the “wrapper object” disappears, so in the last line str has no trace of the property.
This example clearly shows that primitives are not objects.

They can’t store additional data.