A detailed description of JavaScript advanced techniques

Source: Internet
Author: User

The use of the function JavaScript built-in type detection mechanism is not completely reliable. If the Object.prototype.toString () method is not modified, the following security detection method can be used to detect whether it is native: function IsArray (value) {return Object.prototype.toString.call (value) = = "[Object Array]";}  function Isfunction (value) {return Object.prototype.toString.call (value) = = "[Object function]";}   function Isregexp (value) {return Object.prototype.toString.call (value) = = "[Object RegExp]";} This technique can give correct conclusions to any object   scope-safe constructors The general constructors are called using the new operator, but sometimes it is possible to forget that the function is not a constructor, which produces an error. To avoid this error, design the constructor as follows: function person (name,age,job) {    if (this instanceof person) {   This.name=name;  this.age=age;  this.job=job;} else{   return new person (name,age,job);}} The benefit of this is that invoking it, whether or not using the new operator, returns a new instance of the person, avoiding the unintended setting of properties on the global object. Unless you implement inheritance purely on the basis of constructor theft, it is recommended that a scoped-secure constructor be used as a best practice.   Lazy loading function See an example of a change: function createxhr () {   if (typeof xmlhttprequest!= "undefined") {     createxhr=function () {return new XMLHttpRequest ();  };   }else if (typeof activexobject!= "undefined") {                   createxhr=function () {& nbsp;   if (typeof arguments.callee.activexstring!= "string") {   var versions=[" MSXML2. xmlhttp.6.0 "," MSXML2. xmlhttp.3.0 "," MSXML2. XMLHttp "],i,len;   for (i=0,len=versions.length;i<len;i++) {    try{  new ActiveXObject (Versions[i]);   arguments.callee.activexstring=versions[i];  break;} catch (ex) {  //skip;}     }    }return new ActiveXObject ( arguments.callee.activeXString);                   };  }els e{                     createxhr=function () {     THR ow new Error ("No XHR object available.");                        };      }    &nbsP       return createxhr ();  }  this will only lose performance when the function is first executed, and will not be executed at a later time. Considering that this function is browser-based, this change will be great! Another way is to turn each part into a function that returns as a return value. The difference between the two is very subtle. binding function bindings for   functions to create a function, you can invoke another function in a specific this environment with the specified parameters. This technique is often used in conjunction with the callback function and the event handler to preserve the execution environment of the code while passing the function as a variable. Because the this variable exists in the code, and this points to the determined object in the current environment, the problem occurs when you change the execution environment of the code. To solve this problem, a bind () function is implemented in the JavaScript library to solve this problem. A simple bind () function receives a function and an environment and returns a function that invokes the given function in a given environment, and passes all parameters intact. The syntax is as follows: function bind (fn,context) {   return function () {   return fn.apply (context,arguments);     &nbsp}} Note that the arguments used here is not bind (), it is an intrinsic function. var handler={    Message: "Event handled",  handleclick:function (event) {  alert ( this.message);}}; var Btn=document.getelementbyid ("My-btn"); Eventutil.addhandler (BTN, "click", Bind (Handler.handleclick,handler)); ECMASCRIPT5 defines a native bind () method for all functions, further simplifying the operation. var handler={    Message: "Event handled",  handleclick:function (event) {  alert ( this.message);}}; var btn=document.getElementById ("my-btn"); Eventutil.addhandler (BTN, "click", Handler.handleClick.bind (handler)); they are used primarily for event handlers as well as settimeout () and SetInterval (). However, bound functions have more overhead than normal functions, they require more memory, and because multiple function calls are slightly slower, it is best to use them only when necessary.   Function Curry It is used to create a function that has one or more parameters set. The basic way to curry a function is to use a closure to return a function. When a function is called, the returned function also needs to set some incoming arguments. The curry function is typically created dynamically by invoking another function and passing it the function and necessary parameters to be curry. Here is a general way to create a curry function: function Curry (FN) {    var args=array.prototype.slice.call (arguments,1); return function () {   var innerargs=array.prototype.slice.call (arguments);   var finalargs=args.concat (InnerArgs );   return fn.apply (Null,finalargs);}} This change also requires additional overhead   Tamper-resistant objects JavaScript sharing is always a headache. But ECMAScript5 solved the problem. Several methods have been added to specify the behavior of the object. But once the object is defined as tamper-proof, it cannot be undone. This method is not extensible: object.preventextensions (obj); Once you set up anti-scaling, the object cannot add new properties and methods. Existing property methods are not affected, and these property methods can still be modified and deleted. Sealed objects can be used in the method: Object.seal (obj), once the sealed object is set, can not be extended, the existing properties and methods can not be deleted, but the property value can be modified. Frozen objects can be used in the method: Object.freeze (obj), once the frozen object is set, can neither extend nor seal, only through the accessor's set function can modify the value of the property, in other cases is not allowed to modify. Object.isextensible (obj);//detection is extensible Object.isseAled (obj);//detection of closed objectisfrozen (obj);//detection is frozen   advanced timer in order to solve some of the setinterval's execution problems, The following is a chain-setTimeout approach to circumvent: setTimeout (function () {//Add code heresettimeout (arguments.callee,interval);},interval);  yielding processes scripts for long-running reasons: long, deep nested function calls, and a large number of processing loops. Before you expand the loop, you need to consider two important questions: 1: Does the incident have to be done synchronously? 2: Does the data have to be completed sequentially? You can use a timer to separate the loop when you find that some loops take up a large number of events and the answers to both questions. SetTimeout (function () {///takes out the next entry to handle Var item=array.shift ();p rocess (item), and/or entries, and then sets a timer if (array.length>0) { SetTimeout (arguments.callee,interval);}},interval);  function throttling can cause browser crashes or other incidents if the event handlers are not good enough for some continuously triggered events. To circumvent this problem, you can use a timer to throttle the event handlers. The basic idea behind function throttling is that some code cannot be repeated continuously without interruption. This is done by calling the function for the first time, creating a timer, and running the code after the specified interval. When the function is called the second time, it clears the previous timer and sets the other one. If the previous timer has been executed, this operation has no meaning. However, if the previous timer has not been executed, it is actually replacing it with a new timer. The purpose is that the request to execute the function stops for a period of time before execution. The following is the basic form of the pattern: Var processor={     timeoutid:null,  performprocessing:function () {   //actual execution of Handlers}, process:function () {   cleartimeout (This.timeoutid);   var that=this;   this.timeoutid=settimeout (function () {that.performprocessing ();     },1000);  }};p rocessor.process ();//try to start execution as long as the code is executed periodically, it should be throttled. The rate of processing is set according to the requirements, the above example is 1000 milliseconds.   The pattern of custom event events is established using the Observer pattern. The following is a sample code for a custom event, with a note of observation and experience: function Eventtarget () {     this.handlers={};}  EventTarget.prototype={   constructor:EventTarget,   addhandler:function (Type,handler) {       if (typeof this.handlers[type]== "undefined") {    this.handlers[type]=[];     }   This.handlers[type].push (handler);  },   removehandler : function (Type,handler) {       if (This.handlers[type] instanceof Array) {  var handlers =this.handlers[type];  for (Var i=0,len=handlers.length;i<len;i++) {if (handlers[i]===handler) break;    }  handlers.splice (i,1);  }  },   fire:function (event ) {   &nbsp  if (!event.target) event.target=this;  if (This.handlers[event.type] instanceof Array) {   var handlers=this.handlers[event.type];  for (var i=0,len=handlers.length;i<len;i++) {  if ( Handlers[i]===handler) break;    }  }  }     When the other node inherits Eventtarget, it will also have the above event behavior.   Drag and drop this is a very popular custom event. It is very rude to say that if you do not, you should not say that you have learned custom events. var dragdrop=function () {    var dragging=null;function handleevent (event) {    var event= Eventutil.getevent (event); var target=eventutil.gettarget (event);  switch (event.type) {    case "MouseDown":     if (target.className.indexOf ("draggable") >-1) {           & nbsp          dragging=target;    }   break;case   "MouseMove":     if (dragging!=null) {     & nbsp                dragging. style.left=event.clientx+ "px";   dragging.style.top=event.clienty+ "px";  }   break;    case   "MouseUp":      dragging=null;         & nbsp             Break; }};return {  enable:function () {     Eventutil.addhandler (document, "MouseDown", handleevent);  eventutil.addhandler (document, "MouseMove", handleevent);  eventutil.addhandler (document, "MouseUp", handleevent);  },   disable: function () {     Eventutil.removehandler (document, "MouseDown", Handleevent);  Eventutil.removehandler (document, "MouseMove", handleevent);  eventutil.removehandler (document, "MouseUp", handleevent);  }   }} Note that the element is dragged and dropped, he must be absolutely positioned. <div class= "draggable" style= "position:absolute;background:red"/> But some flaws will be found after use, we can make some further modifications Var dragdrop= function () {    var dragging=null,diffx=0,diffy=0;function handLeevent (event) {    var event=eventutil.getevent (event), Var target=eventutil.gettarget (event);  switch (event.type) {    case "MouseDown":     if (target.className.indexOf ("Draggable" ) >-1) {                      dragging=target;  & nbsp;diffx=event.clientx-target.offsetleft;  diffy=event.clienty-target.offsettop;  }    break;case   "MouseMove":     if (dragging!=null) {           & nbsp          dragging.style.left= (EVENT.CLIENTX-DIFFX) + "px";   dragging.style.top= ( Event.clienty-diffy) + "px";  }   break;    case   "MouseUp":      dragging=null;                       Break; }};ret Urn {  enable:function () {     Eventutil.addhandler (doCument, "MouseDown", handleevent)  eventutil.addhandler (document, "MouseMove", Handleevent);  Eventutil.addhandler (document, "MouseUp", Handleevent);  },   disable:function () {     Eventutil.removehandler (document, "MouseDown", handleevent);  eventutil.removehandler (document, " MouseMove ", handleevent);  eventutil.removehandler (document," MouseUp ", Handleevent);  }    } You need to provide some custom events that are triggered Var dragdrop=function () {    var dragdrop=new eventtarget (), dragging=null,diffx=0 , Diffy=0;function handleevent (event) {    var event=eventutil.getevent (event); var target= Eventutil.gettarget (event);  switch (event.type) {    case "MouseDown":     if ( Target.className.indexOf ("draggable") >-1) {                      dragging=target;   diffx=event.clientx-target.offsetleft;  diffy= event.clienty-target.offsettop;   dragdrop.fire ({type: "DragStart", Target:dragging,x:event.clientx,y:event.clienty});  }    break;case   "MouseMove":     if (dragging!=null) {             &NB Sp        dragging.style.left= (EVENT.CLIENTX-DIFFX) + "px";   dragging.style.top= ( Event.clienty-diffy) + "px";   dragdrop.fire ({type: "Drag", Target:dragging,x:event.clientx,y: Event.clienty});  }   break;    case   "MouseUp":       Dragdrop.fire ({type: "Dragend", Target:dragging,x:event.clientx,y:event.clienty});                       dragging=null;               &NBS P       break; }};   dragdrop.enable:function () { eventutil.addhandler (document, " MouseDown ", handleevent);  eventutil.addhandler (document," MouseMove ", handleevent);  eventutIl.addhandler (document, "MouseUp", Handleevent);  };   dragdrop.disable:function () {  Eventutil.removehandler (document, "MouseDown", handleevent);  eventutil.removehandler (document, "MouseMove", handleevent);  eventutil.removehandler (document, "MouseUp", handleevent);  };return DragDrop;     } You can also add more varied event handlers for the event handlers in the switch, so that custom drag-and-drop events are done

JavaScript Advanced tips in a detailed

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.