JS程序设计高级技巧

1、高级函数javascript

  1. 安全类型检测java

    Object.protitype.toString.call(value)
  2. 做用域安全的构造函数数组

    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);
        }
    }
    // 若是你使用构造函数窃取模式的继承且不使用原型链,这个继承极可能被破坏
    function Teacher (name, age, job, salary) {
        // this指向非Peroson 返回新的实例,构造函数中的this属性并未增加
        Person.call(this, name, age, job); 
        this.salary = salary;
    }
    // 解决这个问题的方法是,Teacher.prototype = new Person(),此时一个Teacher实例也是一个Person实例
  3. 惰性载入函数
    在函数被调用的时候再处理函数,在第一次调用的过程当中,该函数会被覆盖为另外一个按合适方式执行的函数安全

    function createXHR () {
        if (typeof XMLHttpRequest != 'undefined) {
            createXHR  = function () {
                return new XMLHttpRequest ();
            }
        } else if (typeof ActiveXObject != 'undefined') {
            createXHR = function () {
                if (typeof arguments.callee.activeString != 'string') {
                    //...
                }
            }
        } else {
            createXHR  = function () {
                // ...
            }
        }
        return createXHR();
    }

    在声明的时候就指定适当的函数,利用匿名函数自运行,return一个合适的函数闭包

  4. 函数绑定
    一个简单的bind函数app

    function bind(fn, context){
        return function() {
            return fn.apply(context, arguments)
        }
    }
  5. 函数柯里化
    函数的柯里化的基本方法和函数绑定是同样的,使用一个闭包返回一个函数,区别是,当函数被调用时,还须要传递一些参数
    柯里化函数动态建立步骤:调用另外一个函数并为它传入要柯里化的函数和必要参数函数

    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)
        }
    }
  6. es5中的防篡改对象
    不可扩展对象this

    Objcect.preventExtensions(obj)   // 设置对象属性是否能够扩展
    Objcect.isExtensible(obj)         // 返回值为bool值,true即该对象能够扩展,false为不可扩展

    密封的对象
    密封对象不可扩展,并且已有成员的[ [ Configurable ] ]特性将被设置为false,这就意味着不能删除属性和方法es5

    Object.seal(obj)     // 设置对象是不是密封
    Object.isSealed    // 返回值为bool值,true即该对象已经密封,false为没有密封

    冻结对象
    冻结的对象既不能够扩展,又是密封的prototype

    Object.freeze(obj)         // 设置对象是否冻结
    Objcet.isForzen(obj)    // 返回值为bool值,true即该对象已经冻结,false为没有冻结
  7. 高级定时器
    除了主Javascript执行进程外,还有一个须要在进程下次一空闲的时执行的代码队列。随着页面在其生命周期中的推移,代码会按照执行顺序添加到队列。
    关于定时器要记住的最重要的事情是:指定的时间间隔表示什么时候将定时器的代码添加到队列,而不是什么时候实际执行代码。
    a.重复的定时器

    使用setInterval()建立的定时器确保了定时器代码规则地插入队列中,这个方式的问题在于定时器代码可能在代码再次被添加到队列以前尚未完成执行,结果致使定时器代码连续运行好几回,而之间没有任何停顿,javascript引擎在使用setInterval时,仅当没有该定时器的代码是才将定时器的代码添加到队列中,可是这样会致使一、某些间隔时间被跳过。

    b.多个定时器之间的执行间隔会比预期的小

    // 解决办法
    setTimeout(function () {
        //处理中
        setTimeout(arguments.callee, interval)
    }, interval)
  8. 数组分块

    function chunk(array, process, context) {
        setTimeout( function() {
            var Item = array.shift();
            process(item)
            if (array.length > 0) {
                setTimeout(arguments.callee, 100)
            }
        }, 100)
    }
  9. 函数节流

    var processor = {
        timeoutId = null,
        // 实际进行处理的方法
        performProcessing: function() {
        // 实际执行的代码
    },
    // 初始处理调用的方法
    process: function () {
        clearTimeout(this.timeouId);
        var that = this;
        this.timeoutId = setTimeout(function () {
            that.performProcessing();
        }, 100)
        }
    }
相关文章
相关标签/搜索