面向对象的程序设计(2)

来源:互联网 发布:淘宝 无忧退货退钱吗? 编辑:程序博客网 时间:2024/05/29 11:59

工厂模式

javascript中没有类这个概念,程序猿就发明了一种函数,用函数来封装以特定接口创建对象的细节

    function createProperty(name,age,job){        var o=new Object();        o.name=name;        o.age=age;        o.job=job;        o.sayAll=function(){            console.log("hello,my name is "+this.name+",I am "+this.age+" years old,I am working as a "+this.job);        }        return o;    }    var person1=createProperty("burning",24,"carry");    person1.sayAll()//hello,my name is burning,I am 24 years old,I am working as a carry

工厂模式解决了创建多个相似对象的问题,但是呢却没有解决对象识别问题,所以就出现了构造函数模式

    function Person(name,age,job){        this.name=name;        this.age=age;        this.job=job;        this.sayJob=function(){            console.log("my job is "+this.job)        }    }    var person1=new Person("burning",24,"carry");    person1.sayJob();//My job is carry

通过这种模式,我们能创建一种特定的类型,而且通过这些构造函数创建出来的实例,即是Object的实例,又是Person的实例,因为原型链的顶端是Object。

但是通过构造函数创建出来的方法,在每个实例上都要创新创建一遍,虽然他们的机制和功能是一模一样的,但是他们却是不相等的,这样就加大了内存的使用。为了解决这个问题,出现了原型模式。

原型模式

我们创建的每个函数都有一个原型属性(prototype),这个属性是一个指针,指向一个对象,他包含可以由特定类型的所有实例共享的属性和方法。我们可以将原型属性直接添加到构造函数中

function Person(){};Person.prototype.name="burning";Person.prototype.age=24;Person.prototype.job="carry"; Person.prototype.sayJob=function(){    console.log(this.name+" is working as a "+this.job);}var person1=new Person()    person1.sayJob();//burning is working as a carryvar person2=new Person();    person2.name="Rotk";//写入新值覆盖,从下向上搜索    person2.job="captain";//写入的值可以通过delete删除    person2.sayJob();//Rotk is working as a captain

我们在创建函数的时候,就会为该函数创建一个prototype属性,这个属性都指向函数的原型对象。默认情况下还会获得一个constructor属性,这个属性包含一个指向prototype的属性所在函数的指针

我们没有办法访问到[[Prototype]],但是可以通过isPrototypeOf()的方法来确定对象之间是否存在这种关系

    console.log(Person.prototype.isPrototypeOf(person1));//true    console.log(Person.prototype.isPrototypeOf(person2));//true

ECMAscript提供了hasOwnProperty()方法来检测一个属性是存在与实例中还是原型中,这个方法在属性存在于实例中才会返回true。

function Person(){};    Person.prototype.name="burning";    Person.prototype.age=28;    Person.prototype.job="carry";    Person.prototype.sayJob=function(){        console.log("my job is "+this.job)    }    var person1=new Person();    var person2=new Person();    console.log(person1.hasOwnProperty("name"));//false    person1.name="jack";    console.log(person1.hasOwnProperty("name"));//true

还有一种方法就是通过in操作符,这个操作符有两种使用方法;

1、单独使用in操作符

function Person(){};    Person.prototype.name="burning";    Person.prototype.age=28;    Person.prototype.job="carry";    Person.prototype.sayJob=function(){        console.log("my job is "+this.job)    }    var person1=new Person();    var person2=new Person();    console.log(person1.hasOwnProperty("name"));//false    console.log("name" in person1);//true    person1.name="jack";    console.log("name" in person1);//true

不管name属性是在原型中还是在实例中,他都会返回true,这样我们就能够通过hasOwnProperty()和in操作符来判断他是在实例中还是原型中。

2、在for-in循环中使用

//IE中不会显示    var o={        toString:function(){            return "BURNING";        },        name:"burning"    }    for(var item in o){        console.log(item);//toString,第二次输出name        if (item=="toString") {            console.log(o.toString())//BURNING,输出顺序为toString,BURNING,name        }    }

取得可枚举属性数组

ECMAscript提供的Object.keys()方法,这个方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组

function Person(){    }    Person.prototype.name="jack";    Person.prototype.age=25;    Person.prototype.job="engineer";    var key=Object.keys(Person.prototype);    console.log(key);          //["name", "age", "job"]    var person1=new Person();    person1.name="burning";    var person1Key=Object.keys(person1);    console.log(person1Key);   //["name"]

ECMAscript5还提供了Object.getOwnPropertyNames()方法。这个方法可以得到所有的属性,不论是否可以枚举,但是会包含构造器属性constructor

原创粉丝点击