📜 ⬆️ ⬇️

JavaScript FAQ: Part 2

image

About 2 months ago, I and TheShock collected questions on JavaScript in the JavaScript FAQ topic : ask questions . The first part, the questions that I got, appeared in just a few days. JavaScript FAQ: Part 1 , but the second part does not and does not work. TheShock is now moving to another country, and therefore he is not up to answers. He asked me to answer his part. So the second part of the answers - those questions that got to me too.

In this part:
  1. Why eval = evil?
  2. What to replace eval?
  3. How to play sound using JS without flash? What formats are supported?
  4. How much use of global variables slow down scripts?
  5. How to disable text selection on JS?
  6. (function () {}) (); What is this design used for?
  7. How to reset events and restore item state?
  8. How to correctly transfer js commands with parameters in ajax applications?
  9. Why in jQuery to pass a window if it is already global and why undefined?
  10. How to find out which way the user turns the mouse wheel?
  11. Does the element have a focus event, if not, is it possible to implement it?
  12. How to make an immutable object (freez)?
  13. Is it possible to make a custom implementation of DomElement so that when parsing for a subset of tags it is used?
  14. What client MVC framework would you recommend?
  15. Referer restrictions bypass
  16. GOTO in javascript
  17. JavaScript inheritance. How ideologically to correctly end up Man and Woman from Human
  18. Is it possible to get a javascript programmer without digging into the layout and server-side?
  19. What is the practice of transferring data from a server to code that executes from .js?
  20. Is it possible to pick up (emulate) the behavior of a DOMInputElement with the help of ordinary DOMElemen (div)?
  21. The problem of private and public methods
  22. How to use JS to simultaneously select and download multiple files?
  23. When downloading files using File and FormData, how do you determine if a user is trying to load a directory?
  24. Does JavaScript have analogs to declarations / annotations (terms from Python / Java, respectively)?

1. Why eval = evil?


1. Eval breaks the usual logic of the program, generating code.
2. It runs the code in the current context and can change it - a potential place to attack. Context can be changed by doing the following trick:
(1,eval)(code); 

What is happening here: eval is the same function that depends on the method of the call. In this case, we change the context to global.

3. Generated eval-th code is more difficult to debug.
4. Eval takes a very long time to complete.
')
Read
Global eval. What are the options?
A bunch of questions on stackoverflow:
stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil
stackoverflow.com/questions/646597/eval-is-evil-so-what-should-i-use-instead
stackoverflow.com/questions/86513/why-is-using-javascript-eval-function-a-bad-idea
...

2. How to replace eval?


The best replacement for eval is a good code structure that does not involve the use of eval. However, eval is not always easy to reject (Parsing JSON, Rezig Shabloonizer).
A good replacement for eval is the Function constructor. But this is the same eval that runs in a global context.
 new Function('return ' + code)(); //    (1,eval)(code); 

3. How to play sound using JS without flash? What formats are supported?


The simplest solution:
 <audio src="http://developer.mozilla.org/@api/deki/files/2926/=AudioTest_(1).ogg" autoplay> Your browser does not support the <code>audio</code> element. </audio> 

But this HTML5 audio is not limited. Formats: Ogg Vorbis, WAV PCM, MP3, AAC, Speex (depends on the specific browser) About formats: Audio format support

Read
HTML5 Audio and Game Development: browser bugs, problems and solutions, ideas
WHATWG - The audio element
MDN - HTML audio
Example: Creating a simple synth
Example: Displaying a graphic with audio samples
Example: Visualizing an audio spectrum
Example: Creating a Web based tone generator

4. How much does the use of global variables slow down scripts?


Depends on the specific browser. In modern browsers this moment is optimized and there is no difference. In older access to the global variable may be 2 times slower.

Here is the test: jsperf.com/global-vs-local-valiable-access
Please consider the fact that this is a test, each operation is run up to 1 million times per second. Even if the increase for the test is 30%, then the actual increase for the 1st operation will be scanty (microseconds).

5. How to disable text selection on JS?


There are several options.

1. Run preventDefault for onselectstart and onmousedown
 var element = document.getElementById('content'); element.onselectstart = function () { return false; } element.onmousedown = function () { return false; } 

2. Add unselectable attribute
 $(document.body).attr('unselectable', 'on') 

3. Add user-select: none style user-select: none
 .g-unselectable { -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; user-select: none; } 

There are crazy solutions to this problem:
4. Timer to clean the Range, TextRange, Selection
I will not explain. How to work with Selection can be found here: Range, TextRange and Selection
5. Render text on canvas
6. Use disabled textarea
 <textarea disabled="disabled" style="border:none;color:#000;background:#fff; font-family:Arial;">      JS? </textarea> 

Here is the microfile for jQuery, using methods 1-3
 $.fn.disableSelection = function() { function preventDefault () { return false; } $(this).attr('unselectable', 'on') .css('-moz-user-select', 'none') .css('-khtml-user-select', 'none') .css('-o-user-select', 'none') .css('-msie-user-select', 'none') .css('-webkit-user-select', 'none') .css('user-select', 'none') .mousedown(preventDefault); .each(function() { this.onselectstart = preventDefault; }); }; 

This plugin will not save from Ctrl + A Ctrl + C in those browsers that do not support user-select or unselectable. Remember: prohibiting excretion is evil.

6. (function () {}) (); What is this design used for?


This is called Immediately-Invoked Function Expression (IIFE) - an expression function that was called immediately after creation.

Here are some ways to create IIFE
 (function(){ /* code */ })(); //  IIFE (function(){ /* code */ }()); //   //     "" true && function(){ /* code */ }(); 0,function(){ /* code */ }(); //  ,      !function(){ /* code */ }(); // Facebook style ~function(){ /* code */ }(); -function(){ /* code */ }(); +function(){ /* code */ }(); //  new new function(){ /* code */ } new function(){ /* code */ }() //   ,    

Where it is used:
1. If you need some variables not to fall into the external environment (like let)
 var APPLICATION_ID = function(){ var keys = { 'pew.ru': 15486, 'pew.pew.ru': 15487, 'pew.pew.pew.ru': 1548 }; return keys[window.location.host]; }(); 

2. The creation of a local circuit - the basis for modules, objects that store the state
 var Module = (function(){ function privateMethod () { }; return { publicMethod: function () { return privateMethod(); } }; }()); 

Read
Immediately-Invoked Function Expression (IIFE)
ECMA-262-3 in detail. Chapter 5. Functions
Functions and function scope
Named function expressions
JavaScript Module Pattern: In-Depth
Closures explained with javascript

7. How to reset events and restore item state?

We have some DOM object with the parameters “A” initially set with HTML and CSS. In the process, we dynamically change the parameters to "B". Is there an easy way to “reset” the state of an object to the original state “A”? Similar to the events. How to roll back to the original state?
Roll back the state of the object does not work. DOM does not store state because elements can be obtained in different ways: directly from html code and generated javascript.

Everything is easier with events. DOM has a good cloneNode method. We simply clone the element with all its contents (it will not have events) and replace the old element with the new one.
 //   $('input').click(function(){alert('')}); function resetEvents(element) { var newElement = element.cloneNode(true); element.parentNode.insertBefore(newElement, element); // fixed by @spmbt element.parentNode.removeChild(element); return newElement; } resetEvents($('input')[0]); //       

8. How to correctly transfer js commands with parameters in ajax applications?

How to correctly transfer js commands with parameters in ajax applications without messing around with quotes? This refers to the data transfer in the ajax system described above. When sending complex commands with several levels of nesting of parameters (for example, "setTimeout ('alert (" Boom !!! ");', 200);") problems are observed when using quotes. How to resolve them or are there any general rules for their design?
To send code from the server to the client is bad. This is similar to the problem with eval. Correctly, quickly and safely transmit not the code, but the data that the browser will process.

You can use RPC. Very transparent RPC can be obtained using NowJS. NowJS is a framework that allows you to perform functions on the server as you will perform them on the client.

Here is an example from the site:
On server: Node.JS server
 var nowjs = require("now"); //   http  var everyone = nowjs.initialize(httpServer); everyone.now.getServerInfo = function(callback){ db.doQuery(callback); } 

On the client
 now.getServerInfo(function(data){ //   }); 

Simple, transparent and beautiful!

Read
Getting Started with NowJS

9. Why in jQuery to pass a window if it is already global and why is it undefined?


jQuery creates a closure and throws window and undefined into it.
1. undefined is sent to reduce the amount of code and work around the problem of overwriting undefined . jQuery often compares with undefined and when compressed, undefined turns into a single-letter variable.
2. window is passed to reduce the amount of code. jQuery applies a good policy, separating the methods of the window from its own, using window.setInterval() and others. When compressing, the window becomes a single-letter variable, the code will be c.setInterval()

10. How to find out which way the user turns the mouse wheel?


There are 2 events that react to the scroll wheel ' DOMMouseScroll ' (Firefox) and ' mousewheel ' (the rest)
How to hang an event, I think everyone understands, let's see its handler
 function wheel(event){ var delta = 0; if (!event) event = window.event; //  IE. //   delta if (event.wheelDelta) { // IE, Opera, safari, chrome -    120 delta = event.wheelDelta/120; } else if (event.detail) { // Mozilla,    3 delta = -event.detail/3; } if (delta) { //    -   ( ). if (event.preventDefault) { event.preventDefault(); } event.returnValue = false; //  IE //    0,    ,   var dir = delta > 0 ? 'Up' : 'Down', } } 

For jQuery There is a Mouse Wheel Plugin jQuery Mouse Wheel Plugin Demos

Not all elements can trigger a scroll event. Depends on the specific browser. Read more: scroll and mousewheel

11. Does the element have a focus event, if not, is it possible to implement it?


Focus is a logical event indicating that the object is currently selected.

If you read the standard, it says that only form elements have focus and blur events: LABEL, INPUT, SELECT, TEXTAREA, and BUTTON. By standard, no other elements can generate this event. For all other elements, there are other DOMFocusIn and DOMFocusOut . IE, as always, has its own events: focusin and focusout .
Firefox is also not particularly compliant with the standard. Some elements of it, except for the form, can throw out focus and blur .

See the test event focus, blur, focusin, focusout, DOMFocusIn, DOMFocusOut :
www.quirksmode.org/dom/events/tests/blurfocus.html
If you listen to all 3 events for an element, then we can determine whether any element has received focus or not.

Read
blur and focus

12. How to make an immutable object (freeze)?


In ECMAScript 3 (a standard that all JavaScript engines support), it was not possible to freeze an object, but in ECMAScript 5 several functions appeared at once that restrict object modification.

Object.preventExtensions is the weakest constraint. The object cannot receive additional parameters.
Object.seal - preventExtensions + any parameters cannot be deleted
Object.freeze - preventExtensions + seal + parameters become read only
These new methods are not supported in all browsers.

Read
New in JavaScript 1.8.5
Object.preventExtensions / seal / freeze Function (JavaScript)
ECMAScript 5 compatibility table

13. Is it possible to make a custom DomElement implementation so that it is used for parsing tags for a subset?


Directly no. DOM is separate from JavaScript and therefore there are some limitations.
1. There are no constructors for specific elements - there is only a factory of elements - document.createElement('') and some string methods for creating elements - String.prototype.anchor and so on. HTMLElement and HTMLDivElement are not constructors.
2. Even if we emulate a constructor, the DOM will “clear” the object after inserting it into the tree.
Example
 //   - var HTMLZzzElement = function () { var self = document.createElement('zzz'); self.__proto__ = HTMLZzzElement.prototype; return self; }; //   HTMLUnknownElement function F(){} F.prototype = HTMLUnknownElement.prototype; HTMLZzzElement.prototype = new F(); HTMLZzzElement.prototype.constructor = HTMLZzzElement; HTMLZzzElement.prototype.pewpewpew = function () {}; //  var zzz = new HTMLZzzElement(); // ,  zzz.innerHTML = 'Yohoho!'; //  console.log(zzz instanceof HTMLZzzElement); // true console.log(zzz instanceof HTMLUnknownElement); // true console.log(zzz instanceof HTMLElement); // true console.log(typeof zzz.pewpewpew); // function //  -   //   DOM document.body.appendChild(zzz); //   zzz = document.querySelector('zzz') //   console.log(zzz instanceof HTMLZzzElement); // false console.log(zzz instanceof HTMLUnknownElement); // true console.log(zzz instanceof HTMLElement); // true console.log(typeof zzz.pewpewpew); // undefined 

However, we can add methods and properties to the prototype of the “class” of the HTML element and then use them in the future:
 HTMLUnknownElement.prototype.pewpewpew = function () {}; console.log(typeof zzz.pewpewpew); // function 

The chain of inheritance "classes" such
Node -> Element -> HTMLElement -> HTMLDivElement/HTMLMetaElement ...
You can add a method to the prototype of the element, but remember that patching other people's objects is bad!

This method will only work in modern browsers. In IE8 and below, html elements are taken as they are out of thin air, so their prototypes cannot be rewritten at a low level:
 >>document.createElement('div').constructor //undefined --   null... 

 >>document.createElement('div') instanceof Object //false -- , ?    toString   >>Object.prototype.toString.call(document.createElement('div')); //"[object Object]" 

14. What client MVC framework would you recommend?


There are many frameworks:
JavaScriptMVC
Backbone.js
Sproutcore
Trimjunction

Look at everything and choose the one you like best. I only worked closely with Backbone.js

Read
Writing complex interfaces with Backbone.js
And again about MVC
MVC in javascript

15. Referer restrictions bypass

On the blabla.ru server there is a picture, the server does not give it away if it is transmitted to Referer from another server (pewpew.com). How to get the contents of the picture and show the user?
Directly from the browser in any way. You can make a server proxy that will change the referer.

16. GOTO in Javascript

Actually the question is how to repeat the behavior of goto in javascript. (You don’t need to tell about good style and goto :) we are talking about generated code. and the restoration of blocks and cycles process is not quite trivial)
JavaScript has tags, but no goto (there is only a reserved word). The label looks the same as in all other languages, but they work differently. The label highlights the block. There may be other marked blocks inside the block. You can jump to the label using break and continue, which are inside this block.

Example:
 loop1: for (var a = 0; a < 10; a++) { if (a == 4) { break loop1; //  4  } alert('a = ' + a); loop2: for (var b = 0; b < 10; ++b) { if (b == 3) { continue loop2; //  3 } if (b == 6) { continue loop1; //   loop1 'finished'    } alert('b = ' + b); } alert('finished') } block1: { alert('hello'); //  'hello' break block1; alert('world'); //     } goto block1; // Parse error - goto  

17. Inheritance in JavaScript. How ideologically to correctly end up Man and Woman from Human


Ideologically correct to use prototype inheritance. The inheritance process is well described in the article " Fundamentals and Misconceptions About JavaScript "

18. Is it possible to get a javascript programmer without digging into the layout and server-side?


Depends on the project, the size of the company and your experience.
If you go to the developer of browser-based games in a large company, then the chance that you will be engaged only in JavaScript is very high. A large company can afford a separate interface programmer, but a small one cannot. Are you lucky without experience in large?
If you are just starting to study the web, then you should go where they want everything.

19. What are the practices of transferring data from the server to the code that is executed from .js?


There are a lot of ways to transfer data: XHR, SSE, WebSockets, JSONP:
Implementing HTTP server push using Server-Sent Events
New XMLHttpRequest2 Features
Creating real-time applications using Server-Sent Events
A lot of things about ajax

Which transport and format you choose depends on the application requirements. For example, if this is a chat, then SSE or WebSockets are better (message delivery time is critical). And if this chat should work cross-domain and in IE6, then you will have to add magic with an iframe or flash.

20. Is it possible to pick up (emulate) the behavior of a DOMInputElement with the help of ordinary DOMElemen (div)?


At the low level is impossible. I explained the reason in the 13th example. You can make a wrapper that will emulate an Input, based on a DOMDivElement.
I sketched a simple emulator jsfiddle.net/azproduction/Kz4d9 - it turned out to be a very input curve (it doesn’t know how to submit, it’sn’t able to lose focus, etc.).
The same problem can be solved more elegantly (thanks to Finom , for reminding me ), adding just 1 attribute: contenteditable, which only desktop browsers support - it turned out the same input, but much better and better jsfiddle.net/azproduction/ZTqRe

21. The problem of private and public methods

If there is a desire to use private variables and methods of objects, in JavaScript there is a problem of access to private methods from public ones. And the privileged methods defined inside the constructor, if I understand correctly, are duplicated for each instance, which is not very good in terms of performance. How about this approach?
TheShock :
Nice approach. At least better than declaring all the methods in the constructor.
 // our constructor function Person(name, age){ this.name = name; this.age = age; }; // prototype assignment Person.prototype = new function(){ // we have a scope for private stuff // created once and not for every instance function toString(){ return this.name + " is " + this.age; }; // create the prototype and return them this.constructor = Person; this._protectedMethod = function (){ // act here }; this.publicMethod = function() { this._protectedMethod(); }; // "magic" toString method this.toString = function(){ // call private toString method return toString.call(this); } }; 

Modular approach:
 var Module = (function (window) { function privateFunction() { console.log('pass'); }; var privateClass = function () {}; var publicClass = function () {}; publicClass.prototype.publicMethod = function () { privateFunction(); // ... }; return { //  publicClass: publicClass }; }(this)); //  (new Module.publicClass()).publicMethod(); 

22. How to use JS to simultaneously select and download multiple files?


Everything is already long and not once written:
1. HTML5 File API: multiple files upload to server
2. Downloading files using HTML5 and how many times we said bad words
3. Browser loading of several files
4. ajax download multiple files with php form
5. Uploading files using html5 File API, with preference and dancers

23. When downloading files using File and FormData, how do you determine if a user is trying to load a directory?

When downloading files using File and FormData - how to determine whether the user is trying to load the directory. The File.type property unfortunately does not help (for some types, as well as for the dir - an empty string), the size property does not help either (ff and safari are shown differently)?
As for File.type , it is said that this is a mime-type and if it is not defined, then it becomes an empty string. mime-type, as usual, is obtained from the file / folder extension. If we drop a real file with the name “pewpew”, then the mime will be "", and if the directory with the name is "pewpew.html", then the mime will be "text/html" . It does not suit us.
Folder size is always 0, but there may be files of 0 bytes. For 100% certainty, this does not suit us.
The standard www.w3.org/TR/FileAPI does not talk about directories separately, but it says that browsers can throw out SECURITY_ERR if the user tries to work with incorrect files (protected, not readable, etc.). of this.

The basis I took the example of Drag and Drop
We will use FileReader to determine the type of resource. In firefox, if you read a folder as a file, then the reader.readAsDataURL method throws an exception. In chrome, this exception is not thrown, but the onerror event is onerror on the reader . We cross and get a function to determine whether the file is or not.
 function isReadableFile(file, callback) { var reader = new FileReader(); reader.onload = function () { callback && callback(true); callback = null; } reader.onerror = function () { callback && callback(false); callback = null; } try { reader.readAsDataURL(file); } catch (e) { callback && callback(false); callback = null; } } 

As a function, I delete the callback for safety so that it does not volunteer again ( FileReader behavior may change in the future).
Jsfiddle.net/azproduction/3sV23/8 usage example

You can, it was limited to file size. If 0, then assume that this is not a file (for it is strange to load a file with a size of 0 bytes).

24. Does JavaScript have analogs to declarations / annotations (terms from Python / Java, respectively)?


There are no direct analogues.

PS If I forgot to answer a question - ask it again. If you have questions that have no answers in the first or second part - ask - they will be in the third;)

Source: https://habr.com/ru/post/124327/


All Articles