2019年9月22日

面向对象的理解

作者 admin

 

思考

var Robot = function(code,number){
    this.code = code;
    this.number = number;
    this.attackMode = function(){
        // 拿小拳拳捶胸口
        ...
    }
}
var robotA = new Robot('r007','666');
var robotB = new Robot('r008','777');
// 用instanceof来识别对象的类型
console.log(robotA instanceof Robot);// true

我们的attackMode这个方法随着这个对象被声明1000个,这个方法也会因为属于不同的实例而在内存中重复声明1000次.在这里,就需要用到原型相关知识来解决存在的问题.

原型

当我们在创建我们的对象时,可以根据相应的需求,将一些属性或者方法挂载在我们原型对象的prototype上面,这样我们每一个new出来的实例,都有一个_proto_属性,该属性指向构造函数的原型对象,通过这个属性,可以让我们的实例对象也访问到原型上面的方法,具体代码看下面:

var Robot = function(code,number){
    this.code = code;
    this.number = number;
}
Robot.prototype.attackMode = function(){
    // 拿小拳拳捶胸口
    ...
} 
var robotA = new Robot('r007','666');
var robotB = new Robot('r008','777');

但这里又出现了一个小问题,如果我们所有的原型上面的方法都像这样来写,那就成下面这个样子了?

Robot.prototype.attackMode = function(){
    // 拿小拳拳捶胸口
    ...
} 
Robot.prototype.defendMode = function(){
    // 拿胸口给别人锤
    ...
}
....

这样的代码是不是看着不够优雅?所以这个时候我们可以采用下面这种写法来替代上面的.

使用构造函数

var Robot = function(code,number){
    this.code = code;
    this.number = number;
}
Robot.prototype = {
    constructor: Robot,
    attackMode: function(){
        // 拿小拳拳捶胸口
        ...
    },
    defendMode: function(){
        // 那胸口给别人锤
        ...
    },
    ...
}

这样看起来好多了。

原型链

需要根据原型链来优雅的实现这一功能了,代码如下:

var Robot = function(code,number){
    this.code = code;
    this.number = number;
}
Robot.prototype = {
    constructor: Robot,
    attackMode: function(){
        // 拿小拳拳捶胸口
        ...
    },
    defendMode: function(){
        // 那胸口给别人锤
        ...
    },
    ...
}

// 机器人SSS,构造函数的继承
var RobotSSS = function (code,number,size){
    Robot.call(this,code,number);
    this.size = size;
}
// 继承原型
RobotSSS.prototype = new Robot(code,number)
// 添加更多方法
RobotSSS.prototype.actingCute = function(){
    //拿大拳拳捶你胸口
    ...
}

js语言中使用构造函数(constructor)作为对象的模板。所谓构造函数,就是提供一个生成对象的模板,并描述对象的基本结构的函数。一个构造函数,可以生成多个对象,每个对象都有相同的结构。

一个作为对象与子对象衔接的产物,负责模板业务,能够批量生产多个对象