日期:2014-05-16  浏览次数:20334 次

所谓的javascript高级技巧

Js学的也差不多了,该是来总结一下Js中一些比较高级的智慧结晶了。基于Js的动态性、对象都是易变的、函数是第一对象等等其他语言所不包含的特性,可以在使用Js的时候创造出更高效、组织性更好的代码。下面提到的一些概念,是不是很熟悉:

分支、惰性实例化、惰性载入函数、单例的两种模式、享元类、函数绑定(纠正函数一个执行上下文)、函数curry化、高级定时器、保护上下文的构造函数、函数节流、自定义事件……

js中的继承、原型、构造函数这些都是老生常谈的了。但是对于构造函数式继承和原型式继承的优缺点,还是有必要了解一下的。原型式继承的主要优点就是共享方法和属性,使得从原型对象中继承出来的子对象都可以在内存中共享全部的方法和属性,这如果是在大型的继承链中将会大大的改善性能和减少内存的使用量。

?

接下来看看上面所罗列的每一个所谓的“高级”技巧的具体细节咧:

  1. 惰性实例化
    惰性实例化所要解决的问题是这样的:避免了在页面中js初始化执行的时候就实例化了类,如果在页面中没有使用到这个实例化的对象,那么这就造成了一定的内存的浪费和性能的消耗,那么如果将一些类的实例化推迟到需要使用它的时候才开始去实例化,那么这就避免了刚才说的问题,做到了“按需供应”,简单代码示例如下:
    var myNamespace = function(){
    var Configure = function(){
    var privateName = "someone's name";
    var privateReturnName = function(){
    return privateName;
    }
    var privateSetName = function(name){
    privateName = name;
    }
    //返回单例对象
    return {
    setName:function(name){
    privateSetName(name);
    },
    getName:function(){
    return privateReturnName();
    }
    }
    }
    //储存configure的实例
    var instance;
    return {
    getInstance:function(){
    if(!instance){
    instance = Configure();
    }
    return instance;
    }
    }
    }();
    //使用方法上就需要getInstance这个函数作为中间量了:
    myNamespace.getInstance().getName();

    上面的就是简单的惰性实例化的示例,但是有一点缺点就是需要使用中间量来调用内部的Configure函数所返回的对象的方法(当然也可以使用变量来储存myNamespace.getInstance()返回的实例对象)。将上面的代码稍微修改一下,就可以只用比较得体的方法来使用内部的方法和属性:

    //惰性实例化的变体
    var myNamespace2 = function(){
    var Configure = function(){
    var privateName = "someone's name";
    var privateReturnName = function(){
    return privateName;
    }
    var privateSetName = function(name){
    privateName = name;
    }
    //返回单例对象
    return {
    setName:function(name){
    privateSetName(name);
    },
    getName:function(){
    return privateReturnName();
    }
    }
    }
    //储存configure的实例
    var instance;
    return {
    init:function(){
    //如果不存在实例,就创建单例实例
    if(!instance){
    instance = Configure();
    }
    //将Configure创建的单例
    for(var key in instance){
    if(instance.hasOwnProperty(key)){
    this[key]=instance[key];
    }
    }
    this.init = null;
    return this;
    }
    }
    }();
    //使用方式:
    myNamespace2.init();
    myNamespace2.getName();

    上面修改了自执行函数返回的对象的代码,在获取Configure函数返回的对象的时候,将该对象的方法赋给myNamespace2,这样,调用方式就发生了一点改变了。

  2. 分支
    分支技术解决的一个问题是处理浏览器之间兼容性的重复判断的问题。普通解决浏览器之间的兼容性的方式是使用if逻辑来进行特性检测或者能力检测,来实现根据浏览器不同的实现来实现功能上的兼容,但问题是,没执行