javascript中的对象创建与继承

js是一门基于原型的面向对象语言,与传统的面向对象如Java,C#相比,它在对象创建及继承上有自己独特的实现方式,本文主要描述js中对象创建及继承的一些实践。

1.对象创建

方式一:工厂模式创建对象

<script>

    function createPerson(name,age,job)
    {
        var o=new Object();
        o.name=name;
        o.age=age;
        o.job=job;
        o.sayName=function(){
            alert(this.name);
        };
        return o;
    }
   //这就是工厂方式创建对象
    var a=createPerson(‘my‘,27,‘student‘);
    a.sayName();
</script>

  这种方式就是将对象属性作为参数传入函数,然后在函数中创建一个新对象再返回给外部使用,属于典型的输入处理输出模式,优点在于简单易于理解也很好的实现了对象的创建和隔离,缺点在于不符合典型OOP语言创建对象实例的做法,而且这样创建出来的对象都属于object类型而不能进一步确定其属于哪个具体的对象类型。

方式二:构造函数创建对象

function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
        this.sayName=function(){
            alert(this.name);
        }

    }
    var p1=new Person(‘my‘,27,‘stu‘);
//    这是使用构造函数来创建对象
    p1.sayName();

  这种方式使用function来模拟一个类,通过调用这个类的构造函数通过new的方式实例化一个对象,这符合经典OOP创造实例对象的做法,同时也可以确定这个实例属于哪个具体的类型,这里是Person类的实例

,但是这种方式造成的缺点在于每个实例的方法都要在创建该对象时被创建一次,function本质上是一个object,这样做对内存浪费较大,实际上,对于多个不同实例他们的方法是共同引用一个function的关系。

方式三:基于原型创建对象

<script>
function Person(){}
Person.prototype.name=‘my‘;
Person.prototype.age=27;
Person.prototype.job=‘stu‘;
Person.prototype.sayName=function() {
    alert(this.name);
}

var p1=new Person();

p1.sayName();
</script>

  这种方式利用每个函数都具有一个原型并且它的多个实例都共享该原型的特性,将该类的属性和方法都挂载到了其原型上,这样做的好处是让多个实例共享了一个方法定义,但是其确定也很明显,即不能通过传参去调用构造函数,构造函数内部的属性都是硬编码的,同时任一实例对其自身的引用类型的属性修改都会影响到其他实例

方式四:构造函数结合原型方式

//属性放在构造函数
    //实例间不会相互影响
    function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
    }
   //方法放在原型中
    //节省内存
    Person.prototype.sayName=function() {
        alert(this.name);
    }

    //使用组合方式创建对象
    var p1=new Person(‘my‘,27,‘stu‘);

    p1.sayName();

  这种方式综合了构造函数和原型的优点,将属性等定义5放在构造函数中,实现了不同实例间的隔离,使之不会互相影响,同时又将方法定义挂载到了原型上,使多个实例共享一个方法定义(方法体),节省了内存空间,但是这种方式实际上将两种方式人为分开了,调用构造函数之后还要再去操作其原型,不符合经典OOP语言创建对象的方式。

方法五:动态原型方式

    function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
        if(typeof this.sayName!=‘function‘){
            this.sayName=function(){
                alert(this.name);
            }
        }
    }

    var p1=new Person(‘my‘,27,‘stu‘);
    p1.sayName();

  该方式将方法四操作原型的代码直接放入到了构造函数中,同时在new该类型的实例的时候进行判断,如果存在function实例,就不创建,否则创建function,实现了多个实例共享一个方法体的单例模式,该模式也是目前广为使用的,比较好的一种对象实例创建方式。

在创建对象较好实现的基础上,我们来讨论js中的继承。

方式一:基于原型链的继承

function SuperType(){
        this.color=[‘a‘,‘b‘,‘c‘];

    }
    function SubType(){

    }
    SubType.prototype=new SuperType();
    var a1= new SubType();
    alert(a1.color);//a,b,c
    a1.color.push(‘d‘);
    var a2=new SubType();
    alert(a2.color);//a,b,c,d

  该方法是将子类的原型指向父类的一个实例,子类就具有了父类的方法和属性,但是存在两个缺点,其一是对于父类引用类型的属性来讲,对于其子类任何实例对该属性的操作,其他实例都会受影响,其二是子类继承无法传参到父类,继承的属性无法控制,只能通过修改完成;

方法二:对象冒充继承

function Person(name){
        this.name=name;
        this.sayName=function(){
            alert(this.name);
        }
    }
    function Worker(name,age){
        Person.call(this,name);
        this.age=age;
    }
    var w1=new Worker(‘my‘,27);
    //alert(w1.name);
    w1.sayName();

  该种继承方式实现了通过传参去初始化子类的实例,达到了多个实例之间属性方法的隔离,即不会相互影响,但是同样对于方法的继承由于是调用call方法执行父类构造函数中的代码,相当于每次都要创造一个function,这样是对内存的浪费。

方法三:组合继承

 function SuperType(name){
        this.name=name;

    }
    SuperType.prototype.sayName=function(){
        alert(this.name);
    }
    function SubType(name,age){
        SuperType.call(this,name);
        this.age=age;
    }
    SubType.prototype=new SuperType();
    SubType.prototype.sayAge=function(){
        alert(this.age);
    }

    var s1=new SubType(‘my‘,27);
    s1.sayAge();
    s1.sayName();

  该种类型的方法是将对属性的继承采用对象冒充的方式,将对方法的继承基于原型链方式,同时对于父类自身其定义也采取上面所讲的属性定义在构造函数中,方法定义在原型中,这样才能够配合这两种不同方式完成组合继承。

时间: 2024-11-10 07:27:28

javascript中的对象创建与继承的相关文章

javascript中的对象继承关系

相信每个学习过其他语言的同学再去学习JavaScript时就会感觉到诸多的不适应, 这真是一个颠覆我们以前的编程思想的一门语言,先不要说它的各种数据类型以及表达 式的不同了,最让我们头疼,恐怕就是面向对象的部分了,在JavaScript中,是没有给定一 个创建对象的关键词的,它不像Java中一个class就可以创建一个对象,在JavaScript中, 对象是一个十分松散的的key-value对的组合,通常,我们在创建对象时,可以通过{}来直 接生成一个对象,就像我们之前所学的,对象中有属性,有行

javascript中的对象之间继承关系

相信每个学习过其他语言的同学再去学习JavaScript时就会感觉到诸多的不适应,这真是一个颠覆我们以前的编程思想的一门语言,先不要说它的各种数据类型以及表达式的不同了,最让我们头疼,恐怕就是面向对象的部分了,在JavaScript中,是没有给定一个创建对象的关键词的,它不像Java中一个class就可以创建一个对象,在JavaScript中,对象是一个十分松散的的key-value对的组合,通常,我们在创建对象时,可以通过{}来直接生成一个对象,就像我们之前所学的,对象中有属性,有行为,这里我

Javascript中的对象和原型(3)

在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型对象实际上就是构造函数的一个实例对象,和普通的实例对象没有本质上的区别.可以包含特定类型的所有实例的共享属性或者方法.这样,如果我们需要修改所有实例中的属性或者方法,就只需要修改一处,就能够影响到所有实例了.因为原型中的属性和方法是共享的.我们可以看下两个图示:       构造函数方式 原型模式方

JavaScript中原型对象的彻底理解

一.什么是原型 原型是Javascript中的继承的继承,JavaScript的继承就是基于原型的继承. 1.1 函数的原型对象 ? 在JavaScript中,我们创建一个函数A(就是声明一个函数), 那么浏览器就会在内存中创建一个对象B,而且每个函数都默认会有一个属性 prototype 指向了这个对象( 即:prototype的属性的值是这个对象 ).这个对象B就是函数A的原型对象,简称函数的原型.这个原型对象B 默认会有一个属性 constructor 指向了这个函数A ( 意思就是说:c

JavaScript中的对象描述符(属性特性)

我们先创建一个对象: var person = { name: "Nicholas", _job: "Software Engineer", sayName: function(){ alert(this.name); }, get job(){ return this._job; }, set job(newJob){ this._job=newJob; } } 在这个对象中,我们定义了一个name属性和一个_job属性:至于以set和get开头的两处代码,他们共

(转)JavaScript中判断对象类型的种种方法

我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一个说明运算数类型的字符串.如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在). 但 type

Javascript中String对象的常用方法

charAt(): 返回在指定位置的字符. charCodeAt(): 返回在指定的位置的字符的 Unicode 编码. var s = "Smile forever!"; s.charAt(2); //i s.charCodeAt(2); //105 concat(): 连接字符串,参数可以是多个字符串. var s1 = "Smile forever!"; var s2 = "extend"; s1.concat(s2); //Smile f

JavaScript中String对象处理HTML标记中文本的方法

big():创建一个<big></big>标记,将这个字符串的字体变大blink():创建一个<blink></blink>标记,使字符串具有闪烁效果bold():创建一个<bold></bold>标记,使字符串加粗显示fixed():创建一个<tt></tt>标记,使字符串固定倾斜显示italics():创建一个<i></i>标记,使字符串以斜体显示small():创建一个<sm

JavaScript中RegExp对象

JavaScript中RegExp对象是保存有关正则表达式模式匹配信息的固有全局对象.使用方法: RegExp.property 必选项property 参数是 RegExp 对象的任意一个属性. RegExp 对象不能直接创建,但始终可以使用.在成功的正则表达式查找完成之前,RegExp 对象各属性的初始值如下所示: 属性简写初始值 index-1www.hljmlyfcyy.com lastIndex-1 lastMatch$&空字符串. lastParen$+空字符串. leftConte