JS面向对象

创建对象的方式

工厂模式

  • 这种模式的缺点是无法识别实例是属于哪一个对象

    function createPerson(name,age,place){
           var obj = {};
           obj.name=name;
           obj.age=age;
           obj.place=place;
           obj.getName= function(){
           console.log('该对象的名字是'+this.name)
            };
           return obj;
    }
    //工厂模式对象创建方式,与寄生构造函数模式作比较
    var person1 = createPerson('lucy','23','swu');
    

构造函数模式

  • 这种模式的优点是可以识别构造函数模式,他的优点是可以识别实例是属于哪一个对象,缺点是无法实现某些函数的共用,即每个方法都要在都要在实例上创建一遍

    function Person(name,age,place) {
            this.name = name;
            this.age = age;
            this.place = place;
            this.getName = function () {
            console.log('Name: '+this.name);
            }
        }
    var person = new Person('lucy',23,'西南大学');
    //Name:lucy
    person.getName();
    //true
    console.log(person instanceof Person); 
    

原型模式

  • 每个函数都有一个prototype属性,这个属性指向这个函数的原型对象,同时每个原型都有一个constructor属性,指向该函数,每个函数的实例都有一个默认的proto属性指向该原型对象,原型的意思有点类似与Java中的静态变量,在内存中分配出一块空间,多个实例共享这个空间。

        function person() {
        }
        person.prototype.name='lucy';
        person.prototype.age=23;
        person.prototype.place="西南大学";
    
        var p1 = new person();
        var p2 = new person();
        //lucy
        console.log(p1.name);
        p1.name='kathy';
        //kathy
        console.log(p1.name);
        //lucy
        console.log(p2.name);
        //false
        alert(p1.name===p2.name); 
    
  • 原型链查找对象

    • 先在该实例中查找有没有这个属性,如果有,就执行,不会再向上一级查找,如果没有找到,就去该实例的原型对象中去寻找。
    • isPrototypeOf()用来判断某个属性是否是该实例有一个指向原型对象的指针。
    • hasOwnProperty()用来判断某个属性是否是某个实例的实例属性。

      function person() {
      
      }
      person.prototype.name='lucy';
      person.prototype.age=23;
      person.prototype.place="西南大学";
      var p1 = new person();
      p1.name='kathy';
      //true
      alert(person.prototype.isPrototypeOf(p1));
      //true
      alert(p1.hasOwnProperty('name'));
      function judge(sx,object) {
          if ( sx in object && !object.hasOwnProperty(sx)){
              alert(true);
          }
          else {
              alert(false);
          }
      }
      //false
      judge('name',p1);
      
  • 原型模式的缺点是无法个性,就是如果一组属性你不想共有,单独使用原型模式是无法实现的。

  • 一种更简单的原型模式,这种模式的特点是会重写整个原型对象,constructor会指向Object而不是该对象。

    Person.prototype={
       constructor:Person, //1
       name:'Lucy',
       age:23,
       place:'swu',
       getName:function () {
           alert(this.name);
       }
    };
    var person = new Person();
    //true
    //将1注释之后输出为false;
    alert(person.constructor===Person);
    

组合使用构造函数模式和原型模式

  • 这种方式可以将构造函数模式和原型模式的优点结合起来,既能实现函数的复用,又可以自定义属性。

        function Person(name,age,job) {
            this.name=name;
            this.age=age;
            this.job=job;
            this.films = ['1','2','3'];
        }
        Person.prototype={
            constructor:Person,
            getName:function () {
                alert(this.name);
            }
        };
    

动态原型模式

  • 这种模式能很好的封装信息,又可以避免多次重写原,注意这里不可以使用字面量的方式创建原型,因为这会切断,实例与新原型之间的联系。

    function Person(name,age,job) {
            this.name=name;
            this.age=age;
            this.job=job;
            this.films = ['1','2','3'];
            if (typeof this.getName != 'function'){
                    Person.prototype.getName = function(){
                        alert(this.name);
                    }
            }
    }
    

寄生构造函数模式

  • 这种模式基本上与工厂模式一样, 只是在创建对象的时候有一点区别

            function Person(name,age,place){
                   var obj = {};
                   obj.name=name;
                   obj.age=age;
                   obj.place=place;
                   obj.getName= function(){
                   console.log('该对象的名字是'+this.name)
                    };
                   return obj;
            }
            //工厂模式对象创建方式,与寄生构造函数模式作比较
            var person1 =new Person('lucy','23','swu'); 
            person1.getName();    
    

稳妥构造函数模式

    function Person(name,age,job){
        var o = new Object();
        o.sayname = function(){
        alert(name);
        };
        return o;
    }

继承

原型链继承

  • 使子对象的原型对象指向父对象的一个实例
  • 子对象的原型对象拥有父对象的所有实例属性,但是也可以访问到父对象的原型方法,以及原型属性,因为此时,子对象的原型对象也指向了父对象的原型对象
  • 原型链继承的搜索方式,先在实例中寻找,然后到子对象的原型对象中寻找,然后到父对象的原型对象中去寻找。

    function Parent() {
        this.name = 'yige';
        this.age = 17;
        this.place = 'swu';
    
    }
    Parent.prototype.getName=function () {
        alert(this.name);
    };
    function Sub() {
    
    }
    Sub.prototype = new Parent();
    //yige
    alert(Sub.prototype.name);
    

借用构造函数

  • 也就是冒充函数的方法,使用 apply 或者 call 方法

        function Parent(name){
            this.name = name;
        }
        function Sub(){
        Parent.call(this,'lucy')
        }
        var sub1 = new Sun();
        //'lucy'
        alert(sub1.name);
    

组合继承

  • 不需要共用的属性使用构造函数继承,需要共用的属性和方法使用原型链继承,这也是最常用的一种继承方式。

原型式继承

  • 基本思想是父对象直接赋值给新对象的原型,新的实例属性各自定义,引用类型公有。

    function object(o){
        function F(){}
        F.prototype = o;
        return new F();
    }
    var person ={
        name: 'kathy',
        friends: ['1','2','3']
    }
    var person1 = object(Person);
    

寄生式继承

  • 基本思路是类似于工厂模式,创建一个函数,这个函数返回一个对象,然后调用这个函数中的方法。

寄生组合式继承

function inPtototype(subType,superType){
    var prototype =object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值