JavaScript之面向对象学习七(动态原型模式和寄生构造函数模式创建自定义类型)

一、动态原型模式

在面向对象学习六中的随笔中,了解到组合构造函数模式和原型模式创建的自定义类型可能最完善的!但是人无完人,代码亦是如此!

有其他oo语言经验的开发人员在看到独立的构造函数和原型时,很可能会感到非常困惑。因为对象在其他oo语言中往往是封装在一块的,而构造函数确是和原型分开的,所以并没有真正意义上的封装,所以动态原型模式正是致力与解决这一问题的一个方案!

动态原型模式将所有的信息都封装在构造函数中(包括原型和实例属性),通过在构造函数中实例化原型(仅在必要的情况下)实现封装,又保持了同时使用构造函数和原型的优点。

    function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
        this.friends=["小超","大超"];
        if(typeof this.sayName!="function") {//这段判断语句的作用是限制Person.prototype属性(原型属性对象)只生成一次,要不然每次实例化一个Person对象都会去写一遍原型对象
            Person.prototype.sayName = function () {
                alert(this.name);
            }
            Person.prototype.sayHello=function(){
                alert("Hello");
            }
        }
    }
    var person=new Person("张三",22,"coder");
    person.sayName();

注意:typeof this.sayName!="function" 中的this,因为创建Person构造函数时,会创建一个prototype属性,该属性实际上就是Person.prototype的原型对象,prototype属性是一个指针,指向Person.prototype的原型对象,所以构造函数拥有所有Person.prototype的原型对象的属性和方法,而创建Person.prototype圆形对象时,会生成一个constructor属性,该属性也是一个指针,指向Person构造函数,用于判断对象实例的类型!

因为Person构造函数够拥有Person.prototype的原型对象的所有属性和方法,所以可以用this判断原型中是否存在该方法!

当第一次实例化Person对象的时候,原型就已经完成初始化,所以当第二次实例化的时候,原型就不会初始化,而且if语句检查的可以是原型的任意属性和方法,不需要每一个都检查,只需要检查其中一个,对于采用这种模式创建的自定义类型,可以同时使用constructor和instanceof来检查他们的类型,代码如下:

    function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
        this.friends=["小超","大超"];
        if(typeof this.sayName!="function") {     //这段判断语句的作用是限制Person.prototype属性(原型属性对象)只生成一次,要不然每次实例化一个Person对象都会去写一遍原型对象
            Person.prototype.sayName = function () {
                alert(this.name);
            }
            Person.prototype.sayHello=function(){
                alert("Hello");
            }
        }
    }
    var person=new Person("张三",22,"coder");
    var person1=new Person("李四",22,"coder");
    alert(person.constructor);   //输出:   Person构造函数所对应的方法体
    alert(person instanceof Person);   //输出:true  说明person是Person对象的实例
    alert(person.constructor==person1.constructor); //输出:true   说明两个实例的原型对象的constructor属性都指向Person构造函数即他们是同一类型

二、寄生构造函数模式

时间: 2024-08-10 17:00:51

JavaScript之面向对象学习七(动态原型模式和寄生构造函数模式创建自定义类型)的相关文章

组合使用构造函数模式和动态原型模式、寄生构造函数模式(创建具有额外方法的特殊数组)

function Bird(name, age) {     this.name = name;     this.age = age;     this.sons = ["Tom", "John"];     //在sayName()方法不存在的情况下,添加到原型中     if (typeof this.sayName != "function") {         Bird.prototype.sayname = function() {

JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍

1.原型模式的重要性不仅仅体现在创建自定义类型方面,就连所有的原生的引用类型(Obejct.Array.String等等)都在构造函数的原型上定义方法和属性.如下代码可以证明: alert(typeof Array.prototype.sort); //输出:function alert(typeof String.prototype.substring); //输出:function 通过原生对象的原型,不仅可以取得所有默认方法的引用,而且可以定义新的方法.可以想修改自己定义对象的原型一样修改

JavaScript之面向对象学九(原型式继承和寄生式继承)

一.原型式继承 该继承模式是由道格拉斯*克罗克福德在2006年提出的实现继承的方法. 模式的基本思路:借助原型可以基于已有的对象创建新的对象,同时还不必因此创建自定义类型. 代码如下: function object(o) { function F() { //定义一个F类型的对象 this.name="111"; } F.prototype=o;//使F的原型对象指向传入对象,也就是说F继承了传入的对象,也相当于用传入的对象重写了F的原型对象 相当于如下代码 /* F.prototy

组合使用构造函数模式和原型模式创建自定义类型

构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性.看下面的例子: function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } Person.prototype = { constructor: Person, sayName: function(){ alert(this

寄生构造函数模式创建对象

这个模式可以在特殊的情况下用来为对象创建构造函数 例子一 假设我们想创建一个具有额外方法的特殊数组. 由于不能直接修改Array构造函数(此为使用寄生构造函数模式的原因) function SpecialArray() {     // 创建数组    var values = new Array();     // 添加值    // values.push.apply(values, arguments);    values.push(...arguments);     // 添加方法 

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

chuangjian自定义类型的最常见方式就是组合使用构造函数模式与原型模式,构造函数模式用于定义实力属性,原型模式定义方法和共享的属性. 寄生构造函数: 原来的写法 var array1 = ['1','2'];var array2 = ['1','2','3'];array1.a = function () { alert(this.length);};array1.a();array2.a = function () { alert(this.length);};array2.a(); 与

JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象

一.仔细分析前面的原型模式创建对象的方法,发现原型模式创建对象,也存在一些问题,如下: 1.它省略了为构造函数传递初始化参数这个环节,结果所有实例在默认的情况下都将取得相同的属性值,这还不是最大的问题! 2.最大的问题是原型中的所有属性是被很多实例所共享的,这种共享对于函数非常合适,对于那些包含基本值的属性也说得过去,因为我们知道可以在实例上添加一个同名属性,可以隐藏原型中的对应属性.但是对于包含应用类型值的属性来说,问题就非常严重了,代码如下: function Person(){ } Per

JavaScript之面向对象学习四原型对象的动态性

1.由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来---即便是先创建了实例后修改原型也是如此.代码如下: function Person(){ } var friend=new Person(); Person.prototype.sayHello=function(){ alert("Hello"); } friend.sayHello(); //输出:Hello 上面这段代码先创建了Person的一个实例,并将其保存在friend中.

javascript之面向对象学习笔记02

Object 原型中的常用方法 1.constructor 语法:构造函数.prototype.constructor, 作用:指向构造函数本身 function Person(){} console.log( Person === Person.prototype.constructor );//true 2.hasOwnProperty 语法:对象.hasOwnProperty( 属性名字 ) 作用:检测属性为对象原生提供还是继承所得 function Person () {} Person