zoukankan      html  css  js  c++  java
  • javascript 快捷操作

    Native JavaScript Functions (Math, Array And String)
    One thing that amazed me is how much easier my life got once I read up thoroughly on the math and string functions of JavaScript. You can use these to avoid a lot of looping and conditions. For example, when I had the task of finding the largest number in an array of numbers, I used to write a loop, like so:

    var numbers = [3,342,23,22,124];
    var max = 0;
    for(var i=0;i<numbers.length;i++){
      if(numbers[i] > max){
        max = numbers[i];
      }
    }
    alert(max);
    This can be achieved without a loop:
    var numbers = [3,342,23,22,124];
    numbers.sort(function(a,b){return b - a});
    alert(numbers[0]);

    Notice that you cannot use sort() on a number array because it sorts lexically. There's a good tutorial on sort() here in case you need to know more.

    Another interesting method is Math.max(). This one returns the largest number from a list of parameters:

    Math.max(12,123,3,2,433,4); // returns 433

    Because this tests for numbers and returns the largest one, you can use it to test for browser support of certain properties:

    var scrollTop= Math.max(
     doc.documentElement.scrollTop,
     doc.body.scrollTop
    );

    This works around an Internet Explorer problem. You can read out thescrollTop of the current document, but depending on the DOCTYPE of the document, one or the other property is assigned the value. When you useMath.max() you get the right number because only one of the properties returns one; the other will be undefined. You can read more about shortening JavaScript with math functions here.

    Other very powerful functions to manipulate strings are split() and join(). Probably the most powerful example of this is writing a function to attach CSS classes to elements.

    The thing is, when you add a class to a DOM element, you want to add it either as the first class or to already existing classes with a space in front of it. When you remove classes, you also need to remove the spaces (which was much more important in the past when some browsers failed to apply classes with trailing spaces).

    So, the original function would be something like:

    function addclass(elm,newclass){
      var c = elm.className;
      elm.className = (c === '') ? newclass : c+' '+newclass;
    }
    You can automate this using the split() and join() methods:
    function addclass(elm,newclass){
      var classes = elm.className.split(' ');
      classes.push(newclass);
      elm.className = classes.join(' ');
    }
    This automatically ensures that classes are space-separated and that yours gets tacked on at the end.

    Event Delegation

    Events make Web apps work. I love events, especially custom events, which make your products extensible without your needing to touch the core code. The main problem (and actually one of its strengths) is that events are removed from the HTML—you apply an event listener to a certain element and then it becomes active. Nothing in the HTML indicates that this is the case though. Take this abstraction issue (which is hard for beginners to wrap their heads around) and the fact that "browsers" such as IE6 have all kind of memory problems and too many events applied to them, and you'll see that not using too many event handlers in a document is wise.

    This is where event delegation comes in. When an event happens on a certain element and on all the elements above it in the DOM hierarchy, you can simplify your event handling by using a single handler on a parent element, rather than using a lot of handlers.

    What do I mean by that? Say you want a list of links, and you want to call a function rather than load the links. The HTML would be:

    <h2>Great Web resources</h2>
    <ul id="resources">
      <li><a href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li>
      <li><a href="http://sitepoint.com">Sitepoint</a></li>
      <li><a href="http://alistapart.com">A List Apart</a></li>
      <li><a href="http://yuiblog.com">YUI Blog</a></li>
      <li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li>
      <li><a href="http://oddlyspecific.com">Oddly specific</a></li>
    </ul>

    The normal way to apply event handlers here would be to loop through the links:

    // Classic event handling example
    (function(){
      var resources = document.getElementById('resources');
      var links = resources.getElementsByTagName('a');
      var all = links.length;
      for(var i=0;i<all;i++){
        // Attach a listener to each link
        links[i].addEventListener('click',handler,false);
      };
      function handler(e){
        var x = e.target; // Get the link that was clicked
        alert(x);
        e.preventDefault();
      };
    })();

    This could also be done with a single event handler:

    (function(){
      var resources = document.getElementById('resources');
      resources.addEventListener('click',handler,false);
      function handler(e){
        var x = e.target; // get the link tha
        if(x.nodeName.toLowerCase() === 'a'){
          alert('Event delegation:' + x);
          e.preventDefault();
        }
      };
    })();

    Because the click happens on all the elements in the list, all you need to do is compare the nodeName to the right element that you want to react to the event.

    Disclaimer: while both of the event examples above work in browsers, they fail in IE6. For IE6, you need to apply an event model other than the W3C one, and this is why we use libraries for these tricks.

    The benefits of this approach are more than just being able to use a single event handler. Say, for example, you want to add more links dynamically to this list. With event delegation, there is no need to change anything; with simple event handling, you would have to reassign handlers and re-loop the list.

    Anonymous Functions And The Module Pattern

    One of the most annoying things about JavaScript is that it has no scope for variables. Any variable, function, array or object you define that is not inside another function is global, which means that other scripts on the same page can access—and will usually override— them.

    The workaround is to encapsulate your variables in an anonymous function and call that function immediately after you define it. For example, the following definition would result in three global variables and two global functions:

    var name = 'Chris';
    var age = '34';
    var status = 'single';
    function createMember(){
      // [...]
    }
    function getMemberDetails(){
      // [...]
    }

    Any other script on the page that has a variable named statuscould cause trouble. If we wrap all of this in a name such asmyApplication, then we work around that issue:

    var myApplication = function(){
      var name = 'Chris';
      var age = '34';
      var status = 'single';
      function createMember(){
        // [...]
      }
      function getMemberDetails(){
        // [...]
      }
    }();
    This, however, doesn't do anything outside of that function. If this is what you need, then great. You may as well discard the name then:
    (function(){
      var name = 'Chris';
      var age = '34';
      var status = 'single';
      function createMember(){
        // [...]
      }
      function getMemberDetails(){
        // [...]
      }
    })();

    If you need to make some of the things reachable to the outside, then you need to change this. In order to reachcreateMember() or getMemberDetails(), you need to return them to the outside world to make them properties of myApplication:

    var myApplication = function(){
      var name = 'Chris';
      var age = '34';
      var status = 'single';
      return{
        createMember:function(){
          // [...]
        },
        getMemberDetails:function(){
          // [...]
        }
      }
    }();
    // myApplication.createMember() and 
    // myApplication.getMemberDetails() now works.

    这个确实可以。

    This is called a module pattern or singleton. It was mentioned a lot by Douglas Crockford and is used very much in the Yahoo User Interface Library YUI. What ails me about this is that I need to switch syntaxes to make functions or variables available to the outside world. Furthermore, if I want to call one method from another, I have to call it preceded by themyApplication name. So instead, I prefer simply to return pointers to the elements that I want to make public. This even allows me to shorten the names for outside use:

    var myApplication = function(){
      var name = 'Chris';
      var age = '34';
      var status = 'single';
      function createMember(){
        // [...]
      }
      function getMemberDetails(){
        // [...]
      }
      return{
        create:createMember,
        get:getMemberDetails
      }
    }();
    //myApplication.get() and myApplication.create() now work.

    最后return的时候返回一个对象,对象内的value是函数名。

    I've called this "revealing module pattern."

    更多:http://coding.smashingmagazine.com/2010/04/20/seven-javascript-things-i-wish-i-knew-much-earlier-in-my-career/

    var numbers = [3,342,23,22,124];

    var max = Math.max.apply( null, numbers ); //342
    do the job as well 

  • 相关阅读:
    LeetCode链表解题模板
    c++中的new、operator new、placement new
    树的前序、中序、后续、层次遍历的递归和非递归解法
    c++Volatile关键词
    南大算法设计与分析课程OJ答案代码(5)--割点与桥和任务调度问题
    c++右值引用以及使用
    c++选择重载函数
    从4行代码看右值引用
    被遗忘的C结构体打包技术
    南大算法设计与分析课程OJ答案代码(4)--变位词、三数之和
  • 原文地址:https://www.cnblogs.com/youxin/p/2692404.html
Copyright © 2011-2022 走看看