Explore strange techniques

The origin of

In engineering practice, we often encounter some strange techniques. Gimmicks are code styles or usage scenarios that have not been imagined in official design or practice. In fact, hoc, similar to React, originally originated from the community, but this scheme has become an official approved scheme. So should we study at ordinary times? Should it be used in engineering, or what kind of strange technology is used.

Two years ago. I haven’t graduated yet, and I chose to enter the front end in the last semester of university. At the same time, one of the reasons I was attracted to the front end camp is js’s strange and crafty skills. At the same time, I am a person who is more curious, so I learned a lot about JS’s strange and crafty skills.

Some of these tricks have either become an integral part of the language, or have disappeared over time, or have been forgotten unconsciously. Since this article is to introduce the knowledge of this area, I would like to introduce some examples from the previous study.

~ operator + indexOf

Before the introduction of es6 includes, we decided that only indexOf could be used to determine string or array contains, but indexOf returned the indexOf the actual element, or -1 if none existed. Because when we were writing C, we used to use 0 for success, 1, 2, 3 for different errors. Because 0 is unique. Truthy Falsy is a concept in c-like languages. It doesn’t mean true or false for bool.

The following table represents JS truthy and Falsy.

Variable types falsy truthy
Boolean false true
string “” Non-empty string
The numerical 0 NaN Any value that is not Falsy
null is no
undefined is no
Object (array), {} and [] no is

For values, we know that 0 is unique to values, and negative 1 is not. So we can change -1 to 0 by using the ~ operator.

~-1
// 0
~1
//-2

Copy the code

Explain performing a NOT operation on each bit. The result is the reverse of a.

9 (base 10) = 00000000000000000000000000001001 (base 2)   
         
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
Copy the code

Because in computers, the first digit represents the symbol position.

And simple to understand. The bitwise nonoperation on any number x results in -(x + 1). That is, -1(and only -1) can be turned into falsy by ~.

var str = 'study pwa';
var searchFor = 'a'; / / this isif (str.indexOf('a') > -1) orif ( -1 * str.indexOf('a') <= 0) another method of condition judgmentif(~ str.indexof (searchFor)) {// searchFor included in string STR}else{// searchFor is not included in string STR}Copy the code

The inertia function

Without learning lazy functions, if you create XHR, you need to make a judgment every time.

function createXHR(){
  var xmlhttp;
  try{
    //firfox,opear,safari
    xmlHttp=new XMLHttpRequest();
  } catch(e) {
    try{
      xmlHttp=new ActiveXobject('Msxm12.XMLHTTP');
    } catch(e) {
      try{
        xmlHttp=new ActiveXobject("Microsoft.XMLHTTP")
      } catch(e) {
        alert("Your browser does not support AJAX")
        return false; }}}return xmlHttp;
}


Copy the code

So now that we’ve learned about lazy functions

function createXHR(){// define XHR, var XHR = null;if(typeof XMLHttpRequest! ='undefined') {
    xhr=new XMLHttpRequest();
    createXHR=function() {returnnew XMLHttpRequest(); // Return a lazy function}}else {
    try{
      xhr=new ActiveXObject("Msxml2.XMLHTTP");
      createXHR=function() {return new ActiveXObject("Msxml2.XMLHTTP");
      }
    } catch(e) {
      try{
        xhr =new ActiveXObject("Microsoft.XMLHTTP");
        createXHR=function() {return new ActiveXObject("Microsoft.XMLHTTP");
        }
      } catch(e) {
        createXHR=function() {returnNull}}}} // The first call also needs to return an XHR object, so you need to return XHRreturn xhr;
}
Copy the code

There is some performance optimization if the code is used for more than two calls. XHR is assigned and returned on the first call, and createXHR is assigned to another function in the hierarchical if judgment.

CreateXHR = is called the second time if the browser has an XMLHttpRequest objectfunction() {returnXMLHttpRequest(); // Return a lazy function directly}Copy the code

This scheme can optimize function calls directly without the need for a second variable. It is also transparent to the caller and does not require any code changes.

Alternative uses of extended operation notation

In my recent study, I read an article about… The shortest way to Conditional Insert Properties into an object literal, The shortest way to Conditional Insert properties into an object literal, this article introduces how to write conditional insert object attributes in The simplest way.

If you have not read this article, you will write the following code:

// Get the phone number const phone = this.state. Phone const person = {name:'gogo', age: 11} // If the phone number is not empty, add it to personif (phone) {
  person.phone = phone
}

Copy the code

However, you can write code like this after reading this article

// Get the phone number const phone = this.state. Phone const person = {name:'gogo', age: 11, ... phone && {phone} }Copy the code

The code above has the same functionality, but much less code.

To understand how the code above works, let’s first introduce… Operator, the extension operator of the object (…) Retrieves all traversable properties of the parameter object and copies them to the current object.

let z = { a: 3, b: 4 };
letn = { ... z }; N // {a: 3, b: 4} // If the object is empty, there is no effect {... {}, a: 1} // {a: 1} // If the extension operator is not followed by an object, it is automatically converted to an object. But if the object has no attributes, an empty object is returned // {... 1} becomes {... Object(1)} but because there is no property {... 1} // {} // undefined} {... null} {... True} // will change to {}Copy the code

See Nguyen Yifeng’s es6 extension operators for a primer on objects

The principle is that the code can be understood as follows:

const obj = { ... (phone && {phone})} // If phone has data,&& will become const obj = {... {phone}} // The object extension operator will be const obj = {phone} but if phone is an empty string or some other Falsy data, the code will short-circuit const obj = {... false ... null ... 0... Undefined} will not add any attributes to the objectCopy the code

Discussion and reflection

The ~ + indexOf operator provides a deeper understanding of paraphis and bits. But after ES6 we can use includes completely. You can do away with ~indexOf entirely.

For lazy functions, this code is not available in typescript. Of course, you can do this by using function variables and adding code.

function createXHR(){} // Change tolet createXHR = function() {/ /... }Copy the code

It can also be seen that TS does not recognize the function name declared by a function as a variable.

Special use of extension operators. For typescript use, the above code can be used in TS, but instead of &&, use the ternary operator

{
   ...phone ? {phone} : {}
}
Copy the code

It is not recommended to use in TS because this code will not be detected by code TS.

const phone = '123'Interface Person {name: string; } // error const person: person = {name:'ccc'. phone ? {phone} : {} }Copy the code

This code is very antithetical to TS, which is primarily a type definition, and using this code to escape from the TS type definition is unacceptable for language and engineering maintenance. The same code that I think is acceptable in JS (but not necessarily in engineering) is not acceptable in TS, which is the difference between languages.

In the comments to this article, the biggest argument is why the simplest code should be used, and the best code should be self-explanatory.

The author also discusses some of his own views, should learn some of their own do not understand things. At the same time, if a thing can explain the context, it can be explained from the original reason, then it is worth learning and using. At the same time, I personally hold the same opinion with the author.

conclusion

  • Js is a flexible language (manual funny).
  • Should learn some strange skill and craftiness more, because many strange skill and craftiness often represent some mixed knowledge, often there will be some novel thinking and experience (why I can’t think of it? At the same time, I can quickly understand when someone else is using a trick or two.
  • Whether or not to use such code in a project depends on the type of team and the project system, not your personal likes and dislikes.

To encourage the

If you think this article is good, I hope you can give me some encouragement and help me star under my Github blog. Blog address

The resources

The shortest way to conditional insert properties into an object literal

Object extension operator