• javascript面向对象编程的3种常见封装形式解析


    javascript如何才能脱离函数式编程,拥抱面向对象编程呢,常见的有3种形式,其它形式可以说都是这3种的变种。
     
    1.直接定义对象直接量的形式
     
    var Util={
        getType:function(obj){
        return Object.prototype.toString.call(obj).replace(/^[object (.+)]$/, '$1').toLowerCase();
        }
    }
    这种是最简单的封装形式,不需要用到原型,也不需要构造器函数,当你只需要一个对象实例的时候,例如一个工具类
    调用形式也不需要使用new,直接的Util.getType(obj);
     
     
    2.构造器函数this绑定对象形式
     
    var User=function (){
        this.userName="windy";
        this.eat=function(){
          console.log("i'm eatting");
       } 
        this.sleep=function(){
          console.log("i'm sleeping")
       }
    }
    这种定义方式不需要用到对象原型,调用的时候需要用到new 操作符,var user=new User();
    需要特别注意的是this的指向问题,this并不是指向User构造器函数的,在调用new User()时生成了一个空对象,
    先不考虑原型,简单的理解相当于调用了var obj={}; User.apply(obj,arguments);
    这种方式每次调用一次new ,都会把通过this.定义的属性和函数全部拷贝一次,虽然对于function来说只是拷贝了引用,只多占了少许内存,但对于像jquery这种有成百上千个实例,方法数量又很多的情况下浪费就比较大了。
     
    因此最优的形式是第3种,原型的方式定义
     
    3.构造器函数原型对象定义形式
    var User=function (){
        this.userName="windy";
        User.prototype.eat=function(){
          console.log("i'm eatting");
       } 
        User.prototype.sleep=function(){
          console.log("i'm sleeping")
       }
    }
    原则上是将属性定义在新生成的对象上,将函数定义在原型上,私有变量用var声明,这样新生成的对象就只包含属性,方法都通过原型链引用,不会污染当前对象。不过像上面这段代码这样定义,一旦需要改类(对象)的名字很麻烦,每个方法都要硬编码User对象,好多重复啊,
     
    改进后:
    var User=function (){
        this.userName="windy";
        User.prototype={
          constructor:User,
         eat:function(){
          console.log("i'm eatting");
       } ,
         sleep:function(){
          console.log("i'm sleeping")
       }
        }
    }
     
    直接给prototype赋值会造成construcor丢失,因为construtor是取原型上的该属性的,如果直接覆盖原型就没这个引用了,所以要单独再赋值回来,当然如果你要不需要用到constructor的话不赋值也没关系。
     
    但还是出现了两个User的硬编码,再进一步可以用var FN=arguments.callee;  FN.prototype={......}
     
     
    总结:2和3两种形式都会返回一个自动创建的新对象,不同的是前者是将方法都定义在了新对象上,而后者并没有把方法定义在新对象上,而是对构造器函数的原型开刀,定义在原型上,生成的新对象虽然啥都没有,但是通过__proto__原型链访问到构造函数的原型就拥有了一切。
     
    另外,在构造器函数中是会自动return 新对象的,但是如果手动定一个return ,则会返回手工定义的对象,这个手工定义的对象原型也是赋值为该构造器函数,如果return的是原始值类型(string,number,boolean),则这个return 会被无视。
     
  • 相关阅读:
    (干货).NET开发丰富的公共类库助你事半功倍(供下载免费使用)
    .NET+模块编排+数据库操作类的封装+分层架构+实体类+Ajax.net+Athem.NET+javascript+Activex组件+用户权限等
    IOS条形码扫描
    企业架构研究总结(2)——问题的由来和基本概念(转载)
    企业架构研究总结(1)——参考资料列表(转载)
    理解.NET中的异常(一)
    [转]《Java Generics and Collections》读书笔记三:协变式覆盖与泛型重载
    [转]《Java Generics and Collections》读书笔记二:子类化与通配符
    转:C++单例模式
    [转] java package import
  • 原文地址:https://www.cnblogs.com/windyfancy/p/5168586.html
Copyright © 2020-2023  润新知