美文网首页
Constructor(构造器)模式

Constructor(构造器)模式

作者: 阿布ccc | 来源:发表于2018-12-04 16:04 被阅读0次
    • 对象创建
      一般使用如下两种方法创建对象:
    //创建对象的两种常用方法
    var newObject = {};
    
    //object构造器的简洁记法
    var newObject = new Object();
    

    有四种方法可以将键值赋值给一个对象

        //创建对象的两种常用方法
        var newObject = {};
    
        //object构造器的简洁记法
        var newObject = new Object();
    
        //1.点语法
        //设置属性
        newObject.somekey1 = "hello world";
    
        //获取属性
        var key1 = newObject.somekey1;
    
        //2.中括号语法
        //设置属性
        newObject['somekey2'] = "hello world2";
    
        //获取属性
        var key2 = newObject['somekey2']
    
        //3.object.defineProperty
        //设置属性
        //obj:必需。目标对象 
        //prop:必需。需定义或修改的属性的名字
        // descriptor:必需。目标属性所拥有的特性
        Object.defineProperty(newObject,'smekey3',{
          value:'for more control of the property behavior',
          writable:true,
          enumerable:true,
          configurable:true
        })
        //上面的简写
        var defineProp=function(obj,key,value){
          let config={}
          config.value=value;
          Object.defineProperty(obj,key,config);
        }
    
        //使用上述方法,先创建一个空的person对象
        var person= Object.create(null)
        //然后设置各个属性
        defineProp(person,'car',"Benze");
        defineProp(person,'dataOfBrithd',"1998");
        defineProp(person,'hasBeard',false);
        
    
        //4.Object.defineproperties
        //设置属性
        Object.defineProperties(newObject,{
          'somekey':{
            value:'Hello World',
            writable:true
          },
          'anotherKey':{
            value:'Foo Bar',
            writable:true
          }
        })
    
        //可以用1,2中获取属性的方法获取3,4方式中的属性
    
    
        //甚至,这些方法都可以用于继承
    
        //用法
        //创建司机dirver对象,继承person对象
        var dirver=Object.create(person)
        //为dirver设置属性
        defineProp(dirver,'topSpeed','100km/h')
        // 获取继承的属性
        console.log(dirver.dataOfBrithd);
        // 获取新设置的属性
        console.log(dirver.topSpeed);
    
    • 基本Constructor(构造器)
      JavaScript中没有类的概念,但是它支持与对象一起用的特殊constructor(构造器)函数。通过在构造器前面加上new关键字,告诉JavaScript像使用构造器一样实例化一个新对象,并且对象成员由该函数定义。在构造器内,关键字this引用新创建的对象。
      我们使用function来模拟创建类,function充当了构造函数。一个基本构造器看起来如下所示:
      //基本构造器
      function Car (name,year,miles){
        this.name=name;
        this.year=year;
        this.miles=miles;
        this.toString=function(){
          return this.name+' was birth in '+ this.year;
        }
      }
      //用法
      var Benze = new Car ('Benze',1998,1000);
      var BYD = new Car ('byd',2009,400);
    
      console.log(Benze.toString())
      console.log(BYD.toString())
    

    上面的function来模拟类很容易和函数混淆。
    我们一般这样做:用一个变量记住一个匿名的function当做是类,function充当了构造函数

      //基本构造器
      var Car = function (name,year,miles){
        this.name=name;
        this.year=year;
        this.miles=miles;
        this.toString=function(){
          return this.name+' was birth in '+ this.year;
        }
      }
      //用法
      var Benze = new Car ('Benze',1998,1000);
      var BYD = new Car ('byd',2009,400);
    
      console.log(Benze.toString())
      console.log(BYD.toString())
    

    我们还可以使用JSON语法来创建类,也就是对象直接量定义方法

    var Car = {
        name: name,
        year: year,
        miles: miles,
        toString:function(){
          return this.name+' was birth in '+ this.year;
        }
    }
    
    • 类的私有属性
      在JavaScript中没有关键字去定义一个类的私有属性,我们需要这样做:
      定义在方法内 也就是function内部,也可以看作成构造函数 的变量,就是私有变量。
    var obj = function Teacher(name) {
    
      //这是私有属性,外界不能访问
      var age = 23;
    
      //这是公有属性,外界可以访问
      this.name = name;
    
      //这是私有方法,外界不可以访问
      function privateMethod() {
        console.log('私有方法')
      }
    
      //想要访问私有变量age,只能在这里编写方法来访问。其余的地方都不行!
    
      //我们通常就是在这里编写公有方法来访问私有属性
    
     };
    
    
    • 类的公有属性和方法
      我们创建公有属性应该在类中指定,创建公有方法应该使用原型对象prototype

    prototype定义的属性就类似于Java的静态成员:
    在原型对象上定义了属性,拥有这个原型对象的function所创建的对象也拥有定义的属性!所以,我们方法中就使用prototype

    var obj = function Teacher(name) {
      this.name = name;
      if( typeof obj._init=="undefined") {
        obj.prototype.setName = function (name) {
          this.name = name;
        };
        obj.prototype.getName = function () {
          alert(this.name);
        };
      }
      obj._init = true;
    };
    

    创建两个不同的Teacher对象,name属性是不一样的。而它们共享同一份setName()和getName()方法

    图片来自网络,如有侵权,立即删除
    值得注意的是:
    prototype定义的属性只可读的
    如果你想要使用具体对象写prototype的属性,实际上并不是写,而是重新为该类定义了一个同名(和prototype同名)的属性。在读取同名属性的时候,优先读取对象上的属性,而不是prototype的。
    • 类的静态属性和方法
      在JavaScript中定义静态属性其实就是通过prototype原型对象来定义的
      定义静态的时机:

      1. 当类的某个值与对象无关,期望所有位置看到的结果是一样的时候,就可以定义为类静态属性。
      2. 如果类的一个方法做的是和具体对象无关的操作,而是做一些工作操作的时候,就可以将这个方法定义为静态的类方法。
    • 总结
      网上看到了,大家可以参考一下
      https://blog.csdn.net/zen_123/article/details/39934269

    function Clazz(){
        this.pubVar = 'public var';// 共有成员变量,类不可访问
        var priVar = 'private var';// 内部私有成员变量,外部不可调用
        Clazz.obj = 'test';// 类变量,对象不可访问
        Clazz.prototype.obj2 = 'test2';
        
        function priMethod(){// 内部私有方法,外部不可调用
            alert("私有方法");
        }
        
        this.specialMethod= function(){// 特权方法,可访问所有成员
            alert("pub:"+ this.pubVar+" |pri:"+priVar+" |obj:"+Clazz.obj+" |obj2:"+Clazz.prototype.obj2);
            //pub:public var |pri:private var |obj:test |obj2:test2
        }
        
        Clazz.prototype.pubMethod = function(){// 公有方法,可访问所有成员
            alert("pub:"+this.pubVar+" |pri:"+priVar+" |obj:"+Clazz.obj+" |obj2:"+Clazz.prototype.obj2);
            //pub:public var |pri:private var |obj:test |obj2:test2
        }
        
        Clazz.staticMethod = function(){// 静态方法
            alert("pub:"+this.pubVar+" |pri:"+priVar+" |obj:"+Clazz.obj+" |obj2:"+Clazz.prototype.obj2);
            //pub:undefined |pri:private var |obj:test |obj2:test2
        }
    }
    var c = new Clazz();
    
    // 用对象去访问成员变量
    // alert("pub:"+c.pubVar+" |pri:"+c.priVar+" |obj:"+c.obj+" |obj2:"+c.obj2);
    // document.writeln("pub:"+c.pubVar+" |pri:"+c.priVar+" |obj:"+c.obj+" |obj2:"+c.obj2+"<br/>");
    //pub:public var |pri:undefined |obj:undefined |obj2:test2
    
    // 用类名去访问成员变量
    // alert("<pub:"+Clazz.pubVar+" |pri:"+Clazz.priVar+" |obj:"+Clazz.obj+" |obj2:"+Clazz.obj2);
    // document.writeln("pub:"+Clazz.pubVar+" |pri:"+Clazz.priVar+" |obj:"+Clazz.obj+" |obj2:"+Clazz.obj2+"<br/>");
    //pub:undefined |pri:undefined |obj:test |obj2:undefined
     
    // 用对象去访问方法
    //c.priMethod();
    // 出错:对象不支持此属性或方法
    
    // c.specialMethod();
    //pub:public var |pri:private var |obj:test |obj2:test2
    
    // c.pubMethod();
    //pub:public var |pri:private var |obj:test |obj2:test2
    
    // Clazz.staticMethod();
    //pub:undefined |pri:private var |obj:test |obj2:test2
    

    相关文章

      网友评论

          本文标题:Constructor(构造器)模式

          本文链接:https://www.haomeiwen.com/subject/mpbbqqtx.html