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

工厂模式

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 carry
var 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值