This is the 27th day of my participation in the August More Text Challenge.

preface

Unary operator, not too noticeable, the role is very big, please do not ignore her! Approach her and fall in love with her!

define

Operators that require only one operand are called unary operators.

Or is the code easy to understand:

+1 // An operand

1 + 2 // Two operands
Copy the code

List of unary operators

The operator instructions
delete Deletes an attribute of an object
void Evaluates the given expression and returns undefined
typeof The basic type of data returned
+ Converts the operation to type Number
Convert the operation to Number and invert it
~ Bitwise non-operator
! Logical non-operators

delete

Basic instructions

The delete operator is used to delete an attribute of an object. True in all cases, except when the property is a non-configurable property of its own. In this case,

  • Non-strict mode returns false.
  • In strict mode, TypeError is raised if the property is an attribute that cannot be configured on its own.

What is a non-configurable property? Take a look at this code to see:

var Employee = {};
Object.defineProperty(Employee, 'name', { 
    configurable: false
});

console.log(delete Employee.name);  // returns false
Copy the code

Set different: false through Object.defineProperty

Matters needing attention

In addition to many attributes that cannot be deleted, note the following:

  1. Delete does not remove attributes from the stereotype

  2. When you delete an array element, the array length is not affected.

  3. The delete method can destroy the shape of the object and also cause V8 to regenerate a new hidden class for the object, resulting in performance degradation.

    For more on delete performance issues, see the Why series: Don’t Use DELETE if not necessary

  4. In strict mode, a SyntaxError is raised if you delete a direct reference to a variable, a parameter to a function, or the function name.

function func(param) {
  // SyntaxError in strict mode.
  console.log(delete param); // false
}
Copy the code

In actual combat

We might not normally encounter a scenario where DELETE is used. We temporarily add temporary methods or intermediate state values to the object, perform a series of operations, and then delete those properties.

Take a classic case, hand write call:

// Node environment is not considered, strict mode is not considered, and freeze is not considered
Function.prototype.call = function (context){
    if (typeof this! = ='function') {
        throw new TypeError('not a funciton')}var argsArr = [];
    for(var i = 1; i< arguments.length; i++){
        argsArr.push("arguments[" + i + "]");
    }    
    var  context  = context == null ? window : Object(context);   
    // Preserve the scene
    var hasFn =  ("__fn__" in context); // Not recommended
    var originFn;
    if(hasFn){
       originFn = context.__fn__;
    }; 
    
    context.__fn__ =  this;
    
    var code = "context.__fn__(" +  argsArr.join(",")  +  ")";
    var result = eval(code);

    if(hasFn){
        context.__fn__ = originFn
    }else {
        delete context.__fn__;
    }
    return result;    
}

Copy the code

We use the __fn__ attribute of the context to refer to the current function, and after execution, we use the __fn__ attribute to delete or restore the original value.

void

Basic instructions

The void operator evaluates the given expression and returns undefined.

Usage scenarios

In some older browsers undefined can be overwritten, see picture: I used IE11 to simulate the effect of IE8

So, so void 0 is better than undefined in this case. The unary operator void has two other common uses in addition to preparing to return undefined:

  1. IIFE executes immediately

;void function(msg){
    console.log(msg)
}("Hello?");

Copy the code

Of course, the more direct way is:

; (function(msg){
    console.log(msg)
})("Hello?");
Copy the code

With the birth of the arrow function, there is a new use: to avoid leakage in the arrow function

button.onclick = () => void doSomething();
Copy the code

typeof

The operator returns a string representing the type of the unevaluated operand.

Typeof null === “object”; Symbol (new in ECMAScript 2015) is also a regular, and BigInt should be no stranger.

typeof BigInt(10) // bigint
typeof Symbol.for("key") // symbol
Copy the code

Temporary dead zone

After adding a block-scoped let and const, using Typeof on the let and const variables in the block before they are declared raises a ReferenceError. We call this a temporary dead zone

typeof newLetVariable; // ReferenceError
typeof newConstVariable; // ReferenceError
typeof newClass; // ReferenceError

let newLetVariable;
const newConstVariable = 'hello';
class newClass{};
Copy the code

specialdocument.all

typeof document.all === 'undefined'; // true
Copy the code

Document. all returns all elements of a page, which is not a standard API.

if(document.all){
    //is IE
}
Copy the code

Other browser vendors find document.all useful, but don’t want to affect existing sites. So document.all returns all elements, but typeof is undefined. Isn’t that funny?

Even to IE10:

Internet Explorer 11 puts an end to this:

A method for determining data types

  1. Typeof identifies the underlying data type and reference data type.
  2. Instanceof identifies reference types, and the rationale for querying prototype chains.
  3. Constructor recognizes reference types, but this object does not work. Contructor can be overwritten as a secondary option.
  4. Object. The prototype. ToString identify types of basic data types and the reference data.
  5. Duck type detection

    Let’s see if the weekly downloads hit8 million is-promiseLibrary source code
function isPromise(obj) {
  return!!!!! obj && (typeof obj === 'object' || typeof obj === 'function') 
  && typeof obj.then === 'function';
}
Copy the code

Of course, the combination is better.

+

Let’s start with an interesting question: find the final output

var a = b = 1;
console.log(+a++ + + +b++)  // 2 = +a + +b == a +b

var a = b = 1;
console.log(++a+ + + ++b)  // 4 = (++a)+ + (++b) == a +b

var a = b = 1;
console.log(-a-- + - -b--) // 0 = -a + -b = -a + b
Copy the code

The unary + operator converts its operand to a numeric type.

The parameter types The results of
Undefined NaN
Null + 0
Boolean True returns 1, otherwise returns 0
String The empty string becomes 0, and if any non-valid numeric character occurs, the result is NaN
Number Returns the original value without conversion
Symbol TypeError
BigInt TypeError
Object toPrimitive=>valueOf=>toString=>Number()
  1. Call the Symbol. ToPrimitive method of the object first, if it does not exist
  2. Call valueOf of the object to get the original value, if not the original value
  3. Call the object’s toString to make it a string
  4. Finally, the string is converted to a Number using the Number() method

More conversion details Unary + Operator

Unary – is very similar to +, except at the end I take the inverse.

~

Invert the bit of its operand, which might be a little confusing. I’ll give you a formula

~x = -(x + 1)
Copy the code

It also gets rid of the decimal place, it gets rid of the decimal place, not round it

~2.3  // -3
~2.6  // -3
Copy the code

For example, ~5 = -(5+1) = -6

console.log(~5);/ / - 6
Copy the code

The not

So we can write an inverse function based on this:

function reveNumber (val: number) {
  return ~val + 1
}
Copy the code

Is derived:

~val + 1 = -(val + 1) + 1 = -val - 1 + 1  = -val
Copy the code

Take an integer bit

I’m sure a lot of people have used this

function getIntPart(val: number){
    return ~~val;
}

toInt(3.4)  / / 3
Copy the code

Derivation: Because ~ will lose the decimal part, you will only be left with the integer part.

 ~~val = ~(-(val + 1))  = -(-(val + 1) + 1) = -(-val -1 + 1) = val
Copy the code

Additional note: Because the numbers ~-1 and ~4294967295 (232-1) are represented in 32-bit form, the result is 0 for both.

!

If not, returns a Boolean value.

Return true for the following cases and false for the rest:

  • null
  • NaN
  • 0
  • "" or ' ' or ` `
  • undefined

Double a (!!!!!)

Two! The operator explicitly forces any value to be converted to the corresponding Boolean value.

!!!!! ({})// true
Copy the code

We often like to use it! And!!!!! To judge is not strict, in fact, this must be cleared, so it is best to add some pre judgment or clear know the data type.

Confused numbers

We can generate numbers and letters from symbols that are useful in confusion, such as:

+ []/ / 0+! + []/ / 1+! + + []! + []/ / 2(! [] + []) [+!!!!! []]// a
Copy the code

Interesting, isn’t it? The main idea is the type conversion + array subscript

Write in the last

If you think it is good, your likes and comments are the biggest motivation for me to move forward.

Please go to the technical exchange groupCome here,. Or add my wechat Dirge-Cloud and learn together.

Refer to the reference

Delete /void/typeof/+/-/~/! Deep understanding in JavaScript delete operator delete ~, in-depth analysis, |, & ^ allelic operator in some applications in JavaScript to remember a school recruit interview memories, late an implicit operator to urinate. Js