Javascript高級関数


 、       
    ①            ,  javascript           ?
        1) typeof            ,          object,      
        2) instanceof           ,                 ,    。
              :var isArray = value instanceof Array;      value     , value    Array              true。  value    frame ,        false
    ②    :    ,       Object    toString()  ,      [object NativeConstructorName]      。          [[Class]]  ,                     。                     ,    toString()          。
        function SafeTypeCheck() {
            if (typeof this.isNumber != "function") {
                // Number  
                SafeTypeCheck.prototype.isNumber = function (value) {
                    return Object.prototype.toString.call(value) == "[object Number]";
                };

                // String  
                SafeTypeCheck.prototype.isString = function (value) {
                    return Object.prototype.toString.call(value) == "[object String]";
                };

                // Boolean  
                SafeTypeCheck.prototype.isBoolean = function (value) {
                    return Object.prototype.toString.call(value) == "[object Boolean]";
                };

                // Array  
                SafeTypeCheck.prototype.isArray = function (value) {
                    return Object.prototype.toString.call(value) == "[object Array]";
                };

                // Function  
                SafeTypeCheck.prototype.isFunction = function (value) {
                    return Object.prototype.toString.call(value) == "[object Function]";
                };

                // RegExp  
                SafeTypeCheck.prototype.isRegExp = function (value) {
                    return Object.prototype.toString.call(value) == "[object RegExp]";
                };

                // Null  
                SafeTypeCheck.prototype.isNull = function (value) {
                    return Object.prototype.toString.call(value) == "[object Null]";
                };

                // Undefined  
                SafeTypeCheck.prototype.isUndefined = function (value) {
                    return Object.prototype.toString.call(value) == "[object Undefined]";
                };

                // Object  ,   JOSN  
                SafeTypeCheck.prototype.isObject = function (value) {
                    return window.JSON && Object.prototype.toString.call(value) == "[object Object]";
                };

                // Native JSON  
                // var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON) == "[object JSON]";
            }
        }
        //   
        var checkType = new SafeTypeCheck();
        alert(checkType.isFunction(function () {}));    // true
        alert(checkType.isArray([]));   // true
        alert(checkType.isString(123)); // false
 、          
    ①  :      :
        function Person(name, age, job){
            this.name = name;
            this.age = age;
            this.job = job;
        }
        var zhang = new Person("zhang", 34, "worker");
        // alert(zhang.name); // zhang
        // alert(window.name); //   
    ②              ,  Person         new ,      ,this   window
        var li = Person("li", 20, "student");
        alert(li.name);     //   
        alert(window.name); // li
    ③  ,                    
        function Person(name, age, job){
            //     new    ,this  Person
            if(this instanceof Person) {
                this.name = name;
                this.age = age;
                this.job = job;
            } else {
            //     new   ,       new   ,        window   
                return new Person(name, age, job);
            }
        }
        var zhang = new Person("zhang", 34, "worker");
        // alert(zhang.name); // zhang
        // alert(window.name); //   
        var li = Person("li", 20, "student");
        alert(li.name);     // li
        alert(window.name); //   
    ④  ,             bug ,              ,          ,                 
        function Student(grade) {
            Person.call(this, "wang", 29, "teacher");
            this.grade = grade;
        }
        var stu = new Student(100);
        //            ,      
        alert(stu.name);    // undefined
        alert(stu.grade);   // 100
    ⑤  ,     。              。
        function Student(grade) {
            Person.call(this, "wang", 29, "teacher");
            this.grade = grade;
        }
        Student.prototype = new Person();
        var stu = new Student(100);
        //    ok 
        alert(stu.name);    // wang
        alert(stu.grade);   // 100
 、      
    ①  :           ?        XHR     :
        function createXHR(){
            if (typeof XMLHttpRequest != "undefined"){      //  ie
                return new XMLHttpRequest();
            } else if (typeof ActiveXObject != "undefined"){    // ie
                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){
                            //  
                        }
                    }
                }
                return new ActiveXObject(arguments.callee.activeXString);
            } else {
                throw new Error("No XHR object available.");
            }
        }
    ②    :        :            XHR  ,      if  ,             。                ,              ,         if                            XHR  。             。
    ③  :            :
        function createXHR(){
            if (typeof XMLHttpRequest != "undefined"){      //  ie
                arguments.callee = function () {
                    return new XMLHttpRequest();
                }
            } else if (typeof ActiveXObject != "undefined"){    // ie
                arguments.callee = function () {
                    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){
                                //  
                            }
                        }
                    }
                    return new ActiveXObject(arguments.callee.activeXString);
                }
            } else {
                arguments.callee = function () {
                    throw new Error("No XHR object available.");
                }
            }
            return arguments.callee();
        }
        alert(new createXHR() instanceof XMLHttpRequest);       // true
    ④  :  ,      ,       if  ,       。
 、    
    ①  :        :
        var handler = {
            message: "Event handled",
            handleClick: function(event){
                alert(this.message);
            }
        };
        var message = "window";
        var btn = document.getElementById("btn");
        EventUtil.addEvent(btn, "click", handler.handleClick);  // undefined,less ie8  window
    ②  :      undefined?      handler.handleClick()   ,  this         DOM     handler( IE8  )。            handler.handleClick()   ,        。this   window。)
        var handler = {
            message: "Event handled",
            handleClick: function(event){
                alert(this.message);
            }
        };
        var message = "window";
        var btn = document.getElementById("btn");
        EventUtil.addEvent(btn, "click", function(event){
            handler.handleClick(event);     // Event handled
        });
    ③    :             ,                   .     apply  call            。
        EventUtil.addEvent(btn, "click", function () {
            return handler.handleClick.call(handler);
        });
    ④     :
        var handler = {
            message: "Event handled",
            handleClick: function(event){
                alert(this.message);
            }
        };
        var message = "window";
        function bind(fn, context) {
            return function () {
                fn.call(context, arguments);
            }
        }
        var btn = document.getElementById("btn");
        EventUtil.addEvent(btn, "click", bind(handler.handleClick, handler));
    ⑤ECMAScript 5              bind()  ,        .
        EventUtil.addEvent(btn, "click", handler.handleClick.bind(handler));
 、     .
    1.  :       ,               。                。
        function add(num1, num2){
            return num1 + num2;
        }
        function curriedAdd(num2){
            //    add()  ,        
            return add(5, num2);
        }
        alert(add(2, 3)); //5
        alert(curriedAdd(3)); //8
    2.            
        function curry(fn){
            //                   
            var args = Array.prototype.slice.call(arguments, 1);
            // alert(args); // 10, 10, 10
            return function(){
                //       (    )     
                var innerArgs = Array.prototype.slice.call(arguments);
                // alert(innerArgs); // 15, 15
                //                   
                var finalArgs = args.concat(innerArgs);
                // alert(finalArgs); // 10, 10, 10, 15, 15
                //                  
                return fn.apply(null, finalArgs);
            };
        }
        function add(){
            var res = 0;
            for(var i = 0, len = arguments.length; i < len; i++) {
                res += arguments[i];
            }
            return res;
        }
        //          
        // fn add  
        // args 10, 10, 10
        // innerArgs 15, 15
        var curried = curry(add, 10, 10, 10);
        alert(curried(15, 15)); // 60
    3.   curry            ,        
        function curry(fn, context){
            //                   
            var args = Array.prototype.slice.call(arguments, 2);
            // alert(args); // btn
            return function(){
                //       (    )     
                var innerArgs = Array.prototype.slice.call(arguments);
                // alert(innerArgs); // [object MouseEvent]
                //                   
                var finalArgs = args.concat(innerArgs);
                alert(finalArgs);       // btn, [object MouseEvent]
                //                  
                return fn.apply(context, finalArgs);
            };
        }
        var handler = {
            message: "Event handled",
            handleClick: function(name, event){
                alert(this.message + ":" + name + ":" + event.type);
            }
        };
        var btn = document.getElementById("btn");
        EventUtil.addEvent(btn, "click", curry(handler.handleClick, handler, "btn"));
    4.ECMAScript 5  bind()          ,   thisvar handler = {
            message: "Event handled",
            handleClick: function(name, event){
                alert(this.message + ":" + name + ":" + event.type);
            }
        };
        var btn = document.getElementById("btn");
        EventUtil.addEvent(btn, "click", handler.handleClick.bind(handler, "btn"));