JS 中创建对象和实现继承的常用方式
发布在JavaScript基础2014年5月11日view:3811
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

创建对象

JS中的面向对象是不完整的,没有标准的类的”声明”方式

最常用的类的声明及对象的创建方式如下,不同的书中对其有不同的命名

function Person(name, age)
{
    // 属性是不相同的,每个有一份
    this.name=name;
    this.age=age;
}

// 方法是相同的,调用同一个
Person.prototype.showName=function ()
{
    alert(this.name);
};
Person.prototype.showAge=function ()
{
    alert(this.age);
};

var p1=new Person('super', 24);
p1.showName();
p1.showAge();

继承
准则:创建出来的子类实例,
1、用 instanceof 检测父类、子类均返回 true;
2、实例的 constructor 指向该子类;
3、子类添加方法,不会添加到父类上;

同样,JS中实现继承也没有一个标准,所以会有很多实现方式,个人觉得比较常用的两种方式如下:

1、组合继承

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

Person.prototype.showName = function ()
{
    alert(this.name);
};
Person.prototype.showAge = function ()
{
    alert(this.age);
};

function Worker(name, age, job)
{
    // 1.继承父级的属性
    Person.apply(this, arguments);

    // 2.添加自己的属性
    this.job = job;
}

// 3.继承父级的方法
Worker.prototype = new Person();
Worker.prototype.constructor = Worker;

// 4.添加自己的方法
Worker.prototype.showJob = function ()
{
    alert(this.job);
};

var oW=new Worker('super', 24, 'Programmer');

oW.showName();
oW.showAge();
oW.showJob();

alert(oW instanceof Person);    // true
alert(oW instanceof Worker);    // true
alert(oW.constructor);          // 指向Worker

唯一的缺点就是调用了两次 Persion 方法。

2、寄生组合模式,解决了组合模式的缺点

function object(obj)
{
    function F(){}
    F.prototype = obj;
    return new F();
}

function inheritPrototype(subType, superType )
{
    var prototype = object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}

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

Person.prototype.showName=function ()
{
    alert(this.name);
};
Person.prototype.showAge=function ()
{
    alert(this.age);
};

function Worker(name, age, job)
{
    // 1.继承父级的属性
    Person.apply(this, arguments);

    // 2.添加自己的属性
    this.job=job;
}

// 3.继承父级的方法
inheritPrototype(Worker, Person);

// 4.添加自己的方法
Worker.prototype.showJob=function ()
{
    alert(this.job);
};

var oW=new Worker('Super', 24, 'Programmer');
oW.showName();
oW.showAge();
oW.showJob();

alert(oW instanceof Person);    // true
alert(oW instanceof Worker);    // true
alert(oW.constructor);          // 指向Worker

个人觉得还是第一种 – 组合继承方便。

继承的封装

组合继承模式的封装

// 参数:父类型(构造函数)、子类的构造、子类的方法
function inherit(parentType, childConstructor, methods)
{
    //Child——子级的构造函数
    function Child()
    {
        //arguments -> ['Super', 24, 'Programmer']
        // 1.继承父级的属性
        parentType.apply(this, arguments);

        // 2.添加子级的属性
        childConstructor.apply(this, arguments);
    }

    // 3.继承父级的方法
    Child.prototype = new parentType();
    Child.prototype.constructor = Child;

    // 4.添加子级的方法
    for(var i in methods)
    {
        Child.prototype[i] = methods[i];
    }

    return Child;
}

// ====================== 测试 ====================

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

Person.prototype.showName = function ()
{
    alert(this.name);
};
Person.prototype.showAge = function ()
{
    alert(this.age);
};

//继承
var Worker = inherit( Person, function (name, age, job){
    this.job = job;
}, {
    showJob: function ()
    {
        alert(this.job);
    }
});

var oW = new Worker('Super', 24, 'Programmer');
oW.showName();
oW.showAge();
oW.showJob();

alert(oW instanceof Person);    // true
alert(oW instanceof Worker);    // true
alert(oW.constructor);          // 指向 Child

这里只简单的封装了一下所谓的组合继承,实际项目中还真是没有用过继承,有点儿心虚,不好意思往下写了,另一个自己封装吧。
继承在游戏中应该用的多一些吧,现在模块化已经流行开来,似乎比面向对象开发更方便。

评论
发表评论
6年前

@xmlovedandan 首先,关于对象的创建和第一种继承方式,这是最常用、最基本的吧;至于寄生组合模式,这个还真是从《Javascript高级程序设计》上看的; 其次,开通该专栏就是干这个事儿的啊,专栏描述里应该说的很清楚吧 o(╯□╰)o 最后,针对该文章,个人觉得对访客唯一有点儿价值的可能就是”继承的封装“了

6年前

艾玛,大哥从高程3抄来的吧。

WRITTEN BY
蛋蛋超人
向钱看 向厚赚 一切都与钱相关!追求卓越 成功会在不经意间追上你!追寻自由,活得更自私些!
TA的新浪微博
PUBLISHED IN
JavaScript基础

主要整理一些JavaScript中的基础知识,本专栏比较偏向于个人笔记,属于一个阶段内遇到的知识整理

我的收藏