EXPRESSIONS AND OPERATIONS Flashcards

1
Q

1) What is a JavaScript expression?:-

A

An expression is a phrase of JavaScript that can be evaluated to produce a value.
* A constant embedded literally in your program is a very simple kind of expression.
* A variable name is also a simple expression that evaluates to whatever value has been assigned to that variable.

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

2) What is a primary expression?:-

A

The simplest forms of expressions. They stand alone and do not include simpler expressions.
* Primary expressions in JavaScript are constant or literal values, certain language keywords,and variable
references.

  • Literals are constant values that are embedded directly in your program. They look like these:
    1.23 // A number literal
    “hello” // A string literal
    /pattern/ // A regular expression literal
  • Some of JavaScript’s reserved words are primary expressions:
    true // Evalutes to the boolean true value
    false // Evaluates to the boolean false value
    null // Evaluates to the null value
    this // Evaluates to the “current” object
  • Finally, the third type of primary expression is a reference to a variable, constant, or property of the
    global object:
    i // Evaluates to the value of the variable i.
    sum // Evaluates to the value of the variable sum.
    undefined // The value of the “undefined” property of the global object
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

3) When any identifier appears by itself in a program, JavaScript assumes it is a variable or constant or
property of the global object and looks up its value. If no variable with that name exists, an attempt to
evaluate a nonexistent variable throws?:-

A

a ReferenceError instead.

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

4) A function definition expression defines?:-

A

a JavaScript function, and the value of such an expression is the newly defined function.

  • In a sense, a function definition expression is a “function literal” in the same way that an object
    initializer is an “object literal.”

// This function returns the square of the value passed to it.
let square = function(x) { return x * x; };

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

5) What is property access expression?:-

A

A property access expression evaluates to the value of an object property or an array element.

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

6) JavaScript defines two syntaxes for property access. List them?:-

A

-> expression . identifier (objects)
-> expression [ expression ] (objects, and arrays)

let o = {x: 1, y: {z: 3}}; // An example object
let a = [o, 4, [5, 6]]; // An example array that contains the object
o.x // => 1: property x of expression o
o.y.z // => 3: property z of expression o.y
o[“x”] // => 1: property x of object o
a[1] // => 4: element at index 1 of expression a
a[2][“1”] / => 6: element at index 1 of expression a[2]
a[0].x // => 1: property x of expression a[0]

  • A property access expression evaluates to the value of an object property or an array element.
  • If the property name includes spaces or punctuation characters, or when it is a number (for arrays), you must use the square
    bracket notation. Square brackets are also used when the property name is not static but is itself the result
    of a computation.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

7) ES2020 adds two new kinds of property access expressions. Name these Conditional Property Access?:-

A

-> expression ?. identifier
-> expression ?.[ expression ]

  • In JavaScript, the values null and undefined are the only two values that do not have properties.
    In a regular property access expression using . or [], you get a TypeError if the expression on the left
    evaluates to null or undefined. You can use ?. and ?.[] syntax to guard against errors of this type.
  • Consider the expression a?.b. If a is null or undefined, then the expression evalu‐ ates to undefined without
    any attempt to access the property b. If a is some other value, then a?.b evaluates to whatever a.b would
    evaluate to (and if a does not have a property named b, then the value will again be undefined).
  • This form of property access expression is sometimes called “optional chaining” because it also works for
    longer “chained” property access expressions like this one:

let a = { b: null };
a.b?.c.d // => undefined

  • a is an object, so a.b is a valid property access expression. But the value of a.b is null, so a.b.c would
    throw a TypeError. By using ?. instead of . we avoid the Type‐ Error, and a.b?.c evaluates to undefined.
  • This means that (a.b?.c).d will throw a TypeError, because that expression attempts to access a property of
    the value unde fined. But—and this is a very important part of “optional chaining”—a.b?.c.d (without the
    parentheses) simply evaluates to undefined and does not throw an error.
  • This is because property access with ?. is “short-circuiting”: if the subexpression to the left of ?.
    evaluates to null or undefined, then the entire expression immediately evaluates to undefined without any
    further property access attempts.
  • Of course, if a.b is an object, and if that object has no property named c, then a.b?.c.d will again throw a
    TypeError, and we will want to use another conditional property access:
    let a = { b: {} };
    a.b?.c?.d // => undefined
  • Conditional property access is also possible using ?.[] instead of []. In the expres‐ sion a?.[b][c], if the
    value of a is null or undefined, then the entire expression immediately evaluates to undefined, and
    subexpressions b and c are never even eval‐ uated. If either of those expressions has side effects, the side
    effect will not occur if a is not defined:

let a; // Oops, we forgot to initialize this variable!
let index = 0;
try {
a[index++]; // Throws TypeError } catch(e) {
index // => 1: increment occurs before TypeError is thrown
}
a?.[index++] // => undefined: because a is undefined
index // => 1: not incremented because ?.[] short-circuits
a[index++] // !TypeError: can’t index undefined.

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

8) In JavaScript, the values null and undefined are the only two values that do not have properties. In a
regular property access expression using . or [], you get a TypeError if the expression on the left evaluates
to null or undefined. What Conditional Property Access syntax can you use to guard against errors of this type?:-

A

-> ?. and
-> ?.[]
* Consider the expression a?.b. If a is null or undefined, then the expression evalu‐ ates to undefined without
any attempt to access the property b. If a is some other value, then a?.b evaluates to whatever a.b would
evaluate to (and if a does not have a property named b, then the value will again be undefined).

  • In JavaScript, the values null and undefined are the only two values that do not have properties.
    In a regular property access expression using . or [], you get a TypeError if the expression on the left
    evaluates to null or undefined. You can use ?. and ?.[] syntax to guard against errors of this type.
  • This form of property access expression is sometimes called “optional chaining” because it also works for
    longer “chained” property access expressions like this one:

let a = { b: null };
a.b?.c.d // => undefined

  • a is an object, so a.b is a valid property access expression. But the value of a.b is null, so a.b.c would
    throw a TypeError. By using ?. instead of . we avoid the Type‐ Error, and a.b?.c evaluates to undefined.
  • This means that (a.b?.c).d will throw a TypeError, because that expression attempts to access a property of
    the value unde fined. But—and this is a very important part of “optional chaining”—a.b?.c.d (without the
    parentheses) simply evaluates to undefined and does not throw an error.
  • This is because property access with ?. is “short-circuiting”: if the subexpression to the left of ?.
    evaluates to null or undefined, then the entire expression immediately evaluates to undefined without any
    further property access attempts.
  • Of course, if a.b is an object, and if that object has no property named c, then a.b?.c.d will again throw a
    TypeError, and we will want to use another conditional property access:
    let a = { b: {} };
    a.b?.c?.d // => undefined
  • Conditional property access is also possible using ?.[] instead of []. In the expres‐ sion a?.[b][c], if the
    value of a is null or undefined, then the entire expression immediately evaluates to undefined, and
    subexpressions b and c are never even eval‐ uated. If either of those expressions has side effects, the side
    effect will not occur if a is not defined:

let a; // Oops, we forgot to initialize this variable!
let index = 0;
try {
a[index++]; // Throws TypeError } catch(e) {
index // => 1: increment occurs before TypeError is thrown
}
a?.[index++] // => undefined: because a is undefined
index // => 1: not incremented because ?.[] short-circuits
a[index++] // !TypeError: can’t index undefined.

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

9) In ES2020, you can also invoke a function using Conditional Invocation ?.() instead of (). explain?:-

A

Normally when you invoke a function, if the expression to the left of the parentheses is null or unde fined or
any other non-function, a TypeError is thrown. With the new ?.() invoca‐ tion syntax, if the expression to the
left of the ?. evaluates to null or undefined, then the entire invocation expression evaluates to undefined and
no exception is thrown.

  • Array objects have a sort() method that can optionally be passed a function argu‐ ment that defines the desired
    sorting order for the array elements. Before ES2020, if you wanted to write a method like sort() that takes an
    optional function argument, you would typically use an if statement to check that the function argument was
    defined before invoking it in the body of the if:

function square(x, log) { // The second argument is an optional function
if (log) { // If the optional function is passed
log(x); // Invoke it
}
return x * x; // Return the square of the argument
}

  • With this conditional invocation syntax of ES2020, however, you can simply write the function invocation using
    ?.(), knowing that invocation will only happen if there is actually a value to be invoked:

function square(x, log) { // The second argument is an optional function
log?.(x); // Call the function if there is one
return x * x; // Return the square of the argument
}

  • Note, however, that ?.() only checks whether the lefthand side is null or undefined. It does not verify that
    the value is actually a function. So the square() function in this example would still throw an exception if you
    passed two numbers to it, for example.
  • Like conditional property access expressions, function invocation with ?.() is short-circuiting: if the value
    to the left of ?. is null or undefined, then none of the argument expressions within the parentheses are
    evaluated:

let f = null, x = 0;
try {
f(x++); // Throws TypeError because f is null
} catch(e) {
x // => 1: x gets incremented before the exception is thrown
}

f?.(x++) // => undefined: f is null, but no exception thrown
x // => 1: increment is skipped because of short-circuiting

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

10) Like conditional property access expressions, function invocation with ?.() is short-circuiting. Explain?:-

A

if the value to the left of ?. is null or undefined, then none of the argument expressions within the parentheses are
evaluated:

let f = null, x = 0;
try {
f(x++); // Throws TypeError because f is null
} catch(e) {
x // => 1: x gets incremented before the exception is thrown
}

f?.(x++) // => undefined: f is null, but no exception thrown
x // => 1: increment is skipped because of short-circuiting

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

11) Conditional invocation expressions with ?.() work just as well for methods as they do for functions.
But because method invocation also involves property access, it is worth taking a moment to be sure you
understand the differences between the following expressions
o.m()
o?.m()
o.m?.() ?:-

A

o.m() // Regular property access, regular invocation
o?.m() // Conditional property access, regular invocation
o.m?.() // Regular property access, conditional invocation

  • In the first expression, o must be an object with a property m and the value of that property must be a
    function.
  • In the second expression, if o is null or undefined, then the expression evaluates to undefined.
    But if o has any other value, then it must have a property m whose value is a function.
  • And in the third expression, o must not be null or undefined. If it does not have a property m, or if the
    value of that property is null, then the entire expression evaluates to undefined.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

12) An object creation expression creates?:-

A

a new object and invokes a function (called a constructor) to initialize the properties of that object.

  • Object creation expressions are like invocation expressions except that they are prefixed with the keyword new:
    new Object()
    new Point(2,3)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

13) The assignment operators and a few other operators expect an operand of type lval. lvalue is a historical
term that means?:-

A

“an expression that can legally appear on the left side of an assignment expression.”

  • In JavaScript, variables, properties of objects, and elements of arrays are lvalues.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

14) Evaluating a simple expression like 2 * 3 never affects the state of your program, and any future
computation your program performs will be unaffected by that evaluation. Some expressions, however, have side
effects, and their evaluation may affect the result of future evaluations. What operations have side effect?:-

A

-> The assignment operators are the most obvious example: if you assign a value to a variable or property,
that changes the value of any expression that uses that variable or property.

-> The ++ and – increment and decrement operators are similar, since they perform an implicit assignment.

-> The delete operator also has side effects: deleting a property is like (but not the same as) assigning
undefined to the property.

-> No other JavaScript operators have side effects, but function invocation and object creation expressions
will have side effects if any of the operators used in the function or constructor body have side effects.

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

15) There is a natural ambiguity to expressions like -32. Depending on the relative precedence of unary minus
and exponentiation, that expression could mean (-3)
2 or -(3**2). Different languages handle this differently,
and rather than pick sides, JavaScript simply?:-

A

makes it a syntax error to omit parentheses in this case, forcing you to write an unambiguous expression.
* The Math.pow() function has been available since the earliest versions of JavaScript, however, and it performs
exactly the same operation as the **(ES2016) operator.

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

16) If you are used to programming languages that distinguish between integer and floating-point numbers, you
might expect to get an integer result when you divide one integer by another. In JavaScript, however, all numbers
are?:-

A

floating-point, so all division operations have floating-point results: 5/2 evaluates to 2.5, not 2.

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

17) Technically, how does the + operator behaves?:-

A

-> If either of its operand values is an object, it converts it to a primitive using the object-to-primitive
algorithm. Date objects are converted by their toString() method, and all other objects are converted via
valueOf(), if that method returns a primitive value. However, most objects do not have a useful valueOf() method,
so they are converted via toString() as well.
-> After object-to-primitive conversion, if either operand is a string, the other is converted to a string and
concatenation is performed.
-> Otherwise, both operands are converted to numbers (or to NaN) and addition is performed.

Here are some examples:
1+2 // => 3: addition
“1” + “2” // => “12”: concatenation
“1” + 2 // => “12”: concatenation after number-to-string
1 + {} // => “1[objectobject]”: concatenation after object-to-string
true + true // => 2: addition after boolean-to-number
2 + null // => 2: addition after null converts to 0.
2 + undefined // => NaN: addition after undefined converts to NaN

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

18 ) It is important to note that when the + operator is used with strings and numbers, it may not be associative.
That is?:-

A

, the result may depend on the order in which operations are performed.

For example:
1 + 2 + “ blind mice” // => “3 blind mice”
1 + (2 + “ blind mice”) // => “12 blind mice”

  • The first line has no parentheses, and the + operator has left-to-right associativity, so the two numbers are
    added first, and their sum is concatenated with the string. In the second line, parentheses alter this order of
    operations: the number 2 is concatenated with the string to produce a new string. Then the number 1 is
    concatenated with the new string to produce the final result.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

19 ) What are unary operands?:-

A

Unary operators modify the value of a single operand to produce a new value.
* In JavaScript, the unary operators all have high precedence and are all right-associative.
* The arithmetic unary operators described in this section (+, -, ++, and –) all convert their single operand
to a number, if necessary. Note that the punctuation characters + and - are used as both unary and binary
operators.

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

20 ) The return value of the ++ operator depends on its position relative to the operand. Explian?:-

A

When used before the operand, where it is known as the pre-increment operator, it increments the operand and
evaluates to the incremented value of that operand. When used after the operand, where it is known as the
post-increment operator, it increments its operand but evaluates to the unincremented value of that operand.

let i = 1, j = ++i; // i and j are both 2
let n = 1, m = n++; // n is 2, m is 1

  • Note that the expression x++ is not always the same as x=x+1. The ++ operator never performs string
    concatenation: it always converts its operand to a number and increments it. If x is the string “1”, ++x is the
    number 2, but x+1 is the string “11”.
  • Also note that, because of JavaScript’s automatic semicolon insertion, you cannot insert a line break between
    the post-increment operator and the operand that precedes it. If you do so, JavaScript will treat the operand as
    a complete statement by itself and insert a semicolon before it.
  • the – operator is similar in nature.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

21 ) The bitwise operators perform?:-

A

low-level manipulation of the bits in the binary representation of numbers.(Although they do not perform traditional
arithmetic opera‐ tions, they are categorized as arithmetic operators here because they operate on numeric
operands and return a numeric value.)

  • Four of these operators perform Boolean algebra on the individual bits of the operands, behaving as if each
    bit in each operand were a boolean value (1=true, 0=false). The other three bitwise operators are used to shift
    bits left and right.
22
Q

22 ) The bitwise operators expect integer operands and behave as if?:-

A

those values were represented as 32-bit integers rather than 64-bit floating-point values.

  • These operators convert their operands to numbers, if necessary, and then coerce the numeric values to 32-bit
    integers by dropping any fractional part and any bits beyond the 32nd.
  • Surprisingly, NaN, Infinity, and -Infinity all convert to 0 when used as operands of these bitwise operators.
  • All of these bitwise operators except&raquo_space;> can be used with regular number operands or with BigInt operands.
23
Q

23 ) The shift operators require a?:-

A

right-side operand between 0 and 31.(After converting this operand to an unsigned 32-bit integer, they drop any bits beyond the 5th, which yields a number in the appropriate range).

  • Surprisingly, NaN, Infinity, and -Infinity all convert to 0 when used as operands of these bitwise operators.
  • All of these bitwise operators except&raquo_space;> can be used with regular number operands or with BigInt operands.
24
Q

24) How does the Bitwise AND (&) work?:-

A

The & operator performs a Boolean AND operation on each bit of its integer arguments. A bit is set in the result only if the corresponding bit is set in both operands. For example, 0x1234 & 0x00FF evaluates to 0x0034.

25
Q

25 ) How does the Bitwise OR (|) work?:-

A

The | operator performs a Boolean OR operation on each bit of its integer argu‐ ments. A bit is set in the
result if the corresponding bit is set in one or both of the operands. For example, 0x1234 | 0x00FF evaluates to 0x12FF.

26
Q

26 ) How does the Bitwise XOR (^) work?:-

A

The ^ operator performs a Boolean exclusive OR operation on each bit of its integer arguments. Exclusive OR means that either operand one is true or operand two is true, but not both. A bit is set in this operation’s result if a corresponding bit is set in one (but not both) of the two operands. For example, 0xFF00 ^ 0xF0F0 evaluates to 0x0FF0.

27
Q

27 ) How does the Bitwise NOT (~) work?:-

A

The ~ operator is a unary operator that appears before its single integer operand. It operates by reversing all
bits in the operand. Because of the way signed integers are represented in JavaScript, applying the ~ operator
to a value is equivalent to changing its sign and subtracting 1. For example, ~0x0F evaluates to 0xFFFFFFF0,
or −16.F

28
Q

28) How does Shift left («) work?:-

A

The &laquo_space;operator moves all bits in its first operand to the left by the number of places specified in the second
operand, which should be an integer between 0 and 31. For example, in the operation a &laquo_space;1, the first bit
(the ones bit) of a becomes the second bit (the twos bit), the second bit of a becomes the third, etc. A zero is
used for the new first bit, and the value of the 32nd bit is lost. Shifting a value left by one position is
equivalent to multiplying by 2, shifting two positions is equiva‐ lent to multiplying by 4, and so on. For
example, 7 &laquo_space;2 evaluates to 28.

29
Q

29 ) How does Shift right with sign (») work?:-

A

The&raquo_space; operator moves all bits in its first operand to the right by the number of places specified in the second
operand (an integer between 0 and 31). Bits that are shifted off the right are lost. The bits filled in on the
left depend on the sign bit of the original operand, in order to preserve the sign of the result. If the first
operand is positive, the result has zeros placed in the high bits; if the first operand is negative, the result
has ones placed in the high bits. Shifting a positive value right one place is equivalent to dividing by 2
(discarding the remainder), shifting right two places is equivalent to integer division by 4, and so on. 7&raquo_space; 1
evaluates to 3, for example, but note that and −7&raquo_space; 1 evaluates to −4.

30
Q

30 ) How does Shift right with zero fill (»>) work?:-

A

The&raquo_space;> operator is just like the&raquo_space; operator, except that the bits shifted in on the left are always zero,
regardless of the sign of the first operand. This is useful when you want to treat signed 32-bit values as if
they are unsigned integers. −1&raquo_space; 4 evaluates to −1, but −1&raquo_space;> 4 evaluates to 0x0FFFFFFF, for example. This is
the only one of the JavaScript bitwise operators that cannot be used with BigInt val‐ ues. BigInt does not
represent negative numbers by setting the high bit the way that 32-bit integers do, and this operator only makes sense for that particular two’s complement representation.

31
Q

31 ) What are JavaScript’s relational operators?:-

A

These operators test for a relationship (such as “equals,” “less than,” or “property of”) between two values and
return true or false depending on whether that relationship exists.

32
Q

32 ) The == operator is a legacy feature of JavaScript and is widely considered to be a source of bugs. You should almost always use?:-

A

=== instead of ==, and !== instead of !=.

33
Q

33 ) JavaScript objects are compared by reference, not by value. An object is equal to itself, but not to any other object. If two distinct objects have the same number of properties, with the same names and values, they are?:-

A

still not equal. Similarly, two arrays that have the same elements in the same order are not equal to each other.

34
Q

34 ) The strict equality operator === evaluates its operands, then compares the two values as follows, performing no type conversion?:-

A

-> If the two values have different types, they are not equal.
-> If both values are null or both values are undefined, they are equal.
-> If both values are the boolean value true or both are the boolean value false, they are equal.
-> If one or both values is NaN, they are not equal. (This is surprising, but the NaN value is never equal to any
other value, including itself! To check whether a value x is NaN, use x !== x, or the global isNaN() function.)
-> If both values are numbers and have the same value, they are equal. If one value is 0 and the other is -0,
they are also equal.
-> If both values are strings and contain exactly the same 16-bit values in the same positions, they are equal.
If the strings differ in length or content, they are not equal. Two strings may have the same meaning and the
same visual appearance, but still be encoded using different sequences of 16-bit values. JavaScript performs no Unicode normalization, and a pair of strings like this is not considered equal to the === or == operators.
-> If both values refer to the same object, array, or function, they are equal. If they refer to different
objects, they are not equal, even if both objects have identical properties.

35
Q

35 ) If the two values do not have the same type, the == operator may still consider them equal. It uses the
following rules and type conversions to check for equality?:-

A

—> If one value is null and the other is undefined, they are equal.
—> If one value is a number and the other is a string, convert the string to a number and try the comparison
again, using the converted value.
—> If either value is true, convert it to 1 and try the comparison again. If either value is false, convert it
to 0 and try the comparison again.
—> If one value is an object and the other is a number or string, convert the object to a primitive and try the
comparison again. An object is converted to a primitive value by either its toString() method or its valueOf() method. The built-in classes of core JavaScript attempt valueOf() conversion before toString() conversion, except for the Date class, which performs toString() conversion.
-> Any other combinations of values are not equal.

“1” == true // => true

  • This expression evaluates to true, indicating that these very different-looking values are in fact equal.
    The boolean value true is first converted to the number 1, and the comparison is done again. Next, the string
    “1” is converted to the number 1. Since both values are now the same, the comparison returns true.
36
Q

36 ) The comparison operators(<, >, <=, >=) test for?:-

A

the relative order (numerical or alphabetical) of their two operands.

  • The operands of these comparison operators may be of any type. Comparison can be performed only on numbers and strings, so operands that are not numbers or strings are converted.
37
Q

37 ) The in operator expects a left-side operand that is_____. It expects a right-side operand that is____.
It evaluates to true if?:-

A

-> a string, symbol, or value that can be converted to a string
-> an object the left-side value is the name of a property of the right-side object. For example:

let point = {x: 1, y: 1}; // Define an object
“x” in point // => true: object has property named “x”
“z” in point // => false: object has no “z” property.
“toString” in point // => true: object inherits toString method
let data = [7,8,9]; // An array with elements (indices) 0, 1, and 2
“0” in data // => true: array has an element “0”
1 in data // => true: numbers are converted to strings
3 in data // => false: no element 3

38
Q

38 ) The instanceof operator expects a left-side operand that is an ___ and a right-side operand that identifies
a ___. The operator evaluates to true if?:-

A

-> object.
-> class of objects
the left- side object is an instance of the right-side class and evaluates to false otherwise.

  • JavaScript, classes of objects are defined by the constructor function that initializes them. Thus, the
    right-side operand of instanceof should be a function.

let d = new Date(); // Create a new object with the Date() constructor
d instanceof Date // => true: d was created with Date()
d instanceof Object // => true: all objects are instances of Object
d instanceof Number // => false: d is not a Number object
let a = [1, 2, 3]; // Create an array with array literal syntax
a instanceof Array // => true: a is an array
a instanceof Object // => true: all arrays are objects
a instanceof RegExp // => false: arrays are not regular expressions

  • Note that all objects are instances of Object. instanceof considers the “superclasses” when deciding whether
    an object is an instance of a class. If the left-side operand of instanceof is not an object, instanceof returns
    false. If the righthand side is not a class of objects, it throws a TypeError.
39
Q

39 ) The && operator can be understood at three different levels. Explain?:-

A

-> At the simplest level, when used with boolean operands, && performs the Boolean AND operation on the two values: it returns true if and only if both its first operand and its second operand are true. If one or both
of these operands is false, it returns false.
-> But && does not require that its operands be boolean values. Recall that all JavaScript values are either
“truthy” or “falsy.” The second level at which && can be understood is as a Boolean AND operator for truthy and falsy values. If both operands are truthy, the operator returns a truthy value. Otherwise, one or both operands must be falsy, and the operator returns a falsy value. In JavaScript, any expression or statement that expects a boolean value will work with a truthy or falsy value, so the fact that && does not always return true or false does not cause practical problems.
-> Notice that this description says that the operator returns “a truthy value” or “a falsy value” but does not
specify what that value is. For that, we need to describe && at the third and final level. This operator starts
by evaluating its first operand, the expression on its left. If the value on the left is falsy, the value of the
entire expression must also be falsy, so && simply returns the value on the left and does not even evaluate the
expression on the right. On the other hand, if the value on the left is truthy, then the overall value of the
expression depends on the value on the righthand side. If the value on the right is truthy, then the overall
value must be truthy, and if the value on the right is falsy, then the overall value must be falsy. So when the
value on the left is truthy, the && operator evaluates and returns the value on the right:

let o = {x: 1};
let p = null;
o && o.x // => 1: o is truthy, so return value of o.x
p && p.x // => null: p is falsy, so return it and don’t evaluate p.x

  • The behavior of && is sometimes called short circuiting, and you may sometimes see code that purposely exploits this behavior to conditionally execute code. For example, the following two lines of JavaScript code have equivalent effects:
    if (a === b) stop(); // Invoke stop() only if a === b
    (a === b) && stop(); // This does the same thing
  • || -OR does also work in this nature(short circuiting)
40
Q

40 ) Unlike the && and || operators, the ! operator converts its operand to a boolean value (using the rules
described in Chapter 3) before inverting the converted value. This means that ! always returns true or false and that you can convert any value x to its equivalent boolean value by applying?:-

A

this operator twice: !!x

41
Q

41 ) It is worth noting DeMorgan’s Laws (two laws of Boolean algebra) that we can express using JavaScript syntax
!(p && q) === (!p || !q) // =>
!(p || q) === (!p && !q) // =>
what do they return?:-

A

// DeMorgan’s Laws
!(p && q) === (!p || !q) // => true: for all values of p and q
!(p || q) === (!p && !q) // => true: for all values of p and q

42
Q

42 ) Like many interpreted languages, JavaScript has the ability to interpret strings of JavaScript source code,
evaluating them to produce a value. JavaScript does this with the?:-

A

global function eval():

eval(“3+2”) // => 5

  • Dynamic evaluation of strings of source code is a powerful language feature that is almost never necessary in practice. If you find yourself using eval(), you should think carefully about whether you really need to use it.
    In particular, eval() can be a security hole, and you should never pass any string derived from user input to
    eval(). With a language as complicated as JavaScript, there is no way to sanitize user input to make it safe to
    use with eval(). Because of these security issues, some web servers use the HTTP “Content-Security-Policy”
    header to disable eval() for an entire website.
43
Q

43 ) eval() expects one argument. If you pass any value other than a string, it simply____. If you pass a string,
it?:-

A

-> returns that value.
attempts to parse the string as JavaScript code, throwing a SyntaxError if it fails. If it successfully parses
the string, then it evaluates the code and returns the value of the last expression or statement in the string
or undefined if the last expression or statement had no value. If the evaluated string throws an exception, that exception propogates from the call to eval().

  • The key thing about eval() (when invoked like this) is that it uses the variable environment of the code that
    calls it. That is, it looks up the values of variables and defines new variables and functions in the same way
    that local code does. If a function defines a local variable x and then calls eval(“x”), it will obtain the
    value of the local variable. If it calls eval(“x=1”), it changes the value of the local variable. And if the
    function calls eval(“var y = 3;”), it declares a new local variable y. On the other hand, if the evaluated string
    uses let or const, the variable or constant declared will be local to the evaluation and will not be defined in
    the calling environment.
  • Similarly, a function can declare a local function with code like this:
    eval(“function f() { return x+1; }”);
  • If you call eval() from top-level code, it operates on global variables and global functions, of course.
44
Q

44 ) What is global eval()?:-

A

It is the ability of eval() to change local variables that is so problematic to JavaScript optimizers. As a
workaround, however, interpreters simply do less optimization on any function that calls eval(). But what should a JavaScript interpreter do, however, if a script defines an alias for eval() and then calls that function by
another name? The JavaScript specification declares that when eval() is invoked by any name other than “eval”, it should evaluate the string as if it were top-level global code. The evaluated code may define new global variables or global functions, and it may set global variables, but it will not use or modify any variables
local to the calling function, and will not, therefore, interfere with local optimizations.

  • A “direct eval” is a call to the eval() function with an expression that uses the exact, unqualified name
    “eval” (which is beginning to feel like a reserved word). Direct calls to eval() use the variable environment of
    the calling context. Any other call—an indirect call—uses the global object as its variable environment and
    cannot read, write, or define local variables or functions. (Both direct and indirect calls can define new
    variables only with var. Uses of let and const inside an evaluated string create variables and constants that
    are local to the evaluation and do not alter the calling or global environment.)

The following code demonstrates:

const geval = eval; // Using another name has global eval
let x = “global”, y = “global”; // Two global variables
function f() { // This function has a local eval
let x = “local”; // Define a local variable
eval(“x += ‘changed’;”); // Direct eval sets local variable
return x; // Return changed local variable
}
function g() { This function has a global eval
let y = “local”; // A local variable
geval(“y += ‘changed’;”); // Indirect eval sets global variable
return y; // Return unchanged local variable
}
console.log(f(), x); // Local variable changed: prints “localchanged global”:
console.log(g(), y); // Global variable changed: prints “local globalchanged”:

  • Notice that the ability to do a global eval is not just an accommodation to the needs of the optimizer; it is
    actually a tremendously useful feature that allows you to execute strings of code as if they were independent,
    top-level scripts.
45
Q

45 ) Strict mode imposes further restrictions on the behavior of the eval() function and even on the use of the
identifier “eval”. When eval() is called from strict-mode code, or when the string of code to be evaluated itself
begins with a “use strict” directive, then eval() does a local eval with a private variable environment.
This means?:-

A

that in strict mode, evaluated code can query and set local variables, but it cannot define new variables or
functions in the local scope.

  • Furthermore, strict mode makes eval() even more operator-like by effectively making “eval” into a reserved word. You are not allowed to overwrite the eval() function with a new value. And you are not allowed to declare a variable, function, function parameter, or catch block parameter with the name “eval”.
46
Q

46 ) The conditional operator is the only ternary operator (three operands) in JavaScript and is sometimes
actually called the?:-

A

ternary operator. This operator is sometimes written ?:, although it does not appear quite that way in code.
Because this operator has three operands, the first goes before the ?, the second goes between the ? and the :, and the third goes after the :. It is used like this:

x > 0 ? x : -x // The absolute value of x

  • While you can achieve similar results using the if statement, the ?: operator often provides a handy shortcut.
    Here is a typical usage, which checks to be sure that a variable is defined (and has a meaningful, truthy value)
    and uses it if so or provides a default value if not:

greeting = “hello “ + (username ? username : “there”);

47
Q

47 ) The first-defined operator ?? evaluates to its first defined operand: if its left operand is not null and
not undefined, it returns that value. Otherwise, it returns the value of the right operand. Like the && and ||
operators, ?? is short-circuiting: it only evaluates its second operand if the first operand evaluates to null or
undefined. If the expression a has no side effects, then the expression a ?? b is equivalent to?:-

A

(a !== null && a !== undefined) ? a : b

  • Here are examples showing how ?? works when the first operand is falsy. If that operand is falsy but defined, then ?? returns it. It is only when the first operand is “nullish” (i.e., null or undefined) that this operator evaluates and returns the second operand:

let options = { timeout: 0, title: “”, verbose: false, n: null };
options.timeout ?? 1000 // => 0: as defined in the object
options.title ?? “Untitled” // => “”: as defined in the object
options.verbose ?? true // => false: as defined in the object
options.quiet ?? false // => false: property is not defined
options.n ?? 10 // => 10: property is null

  • Note that the timeout, title, and verbose expressions here would have different val‐ ues if we used || instead of ??.
48
Q

48 ) typeof is a unary operator that is placed before its single operand, which can be of any type. Its value is?:-

A

a string that specifies the type of the operand

49
Q

49 ) What are the 9 Values returned by the typeof operator?:-

A

undefined - “undefined”
null - “object”
true or false - “boolean”
any number or NaN - “number”
any BigInt - “bigint”
any string - “string”
any symbol - “symbol”
any function - “function”
any nonfunction object - “object”

You might use the typeof operator in an expression like this:
// If the value is a string, wrap it in quotes, otherwise, convert
(typeof value === “string”) ? “’” + value + “’” : value.toString()

  • Because typeof evaluates to “object” for all object and array values other than functions, it is useful only
    to distinguish objects from other, primitive types. In order to distinguish one class of object from another,
    you must use other techniques, such as the instanceof operator, the class attribute, or the con structor
    property.
50
Q

50 ) delete is a unary operator that attempts to?:-

A

delete the object property or array element specified as its operand. Like the assignment, increment, and
decrement operators, delete is typically used for its property deletion side effect and not for the value it
returns. Some examples:

let o = { x: 1, y: 2}; // Start with an object
delete o.x; // Delete one of its properties
“x” in o // => false: the property does not exist anymore

let a = [1,2,3]; // Start with an array
delete a[2]; // Delete the last element of the array
2 in a // => false: array element 2 doesn’t exist anymore
a.length // => 3: note that array length doesn’t change, though

  • Note that a deleted property or array element is not merely set to the undefined value. When a property is
    deleted, the property ceases to exist. Attempting to read a nonexistent property returns undefined, but you can test for the actual existence of a property with the in operator. Deleting an array element leaves a “hole” in the array and does not change the array’s length. The resulting array is sparse.
51
Q

51 ) delete expects its operand to be an lvalue. If it is not an lvalue, the operator takes no action and returns
true. Otherwise, delete attempts to?:-

A

delete the specified lvalue. delete returns true if it successfully deletes the specified lvalue. Not all
properties can be deleted, however: non-configurable properties are immune from deletion.

  • In strict mode, delete raises a SyntaxError if its operand is an unqualified identifier such as a variable,
    function, or function parameter: it only works when the operand is a property access expression. Strict mode
    also specifies that delete raises a TypeError if asked to delete any non-configurable (i.e., nondeleteable)
    property. Out‐side of strict mode, no exception occurs in these cases, and delete simply returns false to
    indicate that the operand could not be deleted.

Here are some example uses of the delete operator:

let o = {x: 1, y: 2};
delete o.x; // delete one of the object properties: return true.
typeof o.x; // property does not exist: returns undefined
delete o.x; // delete a nonexistent property: return true
delete 1; // This makes no sense but retuns true
// Can’t delete a variable; returns false, or SyntaxError in strict mode. delete o;
// Undeletable property: returns false, or TypeError in strict mode.
delete Object.prototype;

52
Q

52 ) void is a unary operator that appears before its single operand, which may be of any type. This operator is?:-

A

unusual and infrequently used; it evaluates its operand, then discards the value and returns undefined.
Since the operand value is discarded, using the void operator makes sense only if the operand has side effects.