我理解中的JS面向对象

面向对象,已经成为日常编程过程中绕不过去的一道坎了.熟练的掌握面向对象相关知识,包括如何创建对象,工厂模式的使用,构造函数的产生,原型的出现,原型链的使用等一系列知识,对我们更好的编写组织我们的代码有着革命性的意义.

这里我想通过代码的演示,来向大家展示我理解中的JS面向对象相关知识.

Talk is cheap,show mew the code!

创建对象

假如现在需要我们来编写一个游戏,游戏里面的用兵单位是机器人,这时我们需要创建一个机器人对象.这里我们可以这样来创建我们的机器人对象.(伪码为主,别太认真)

// 用 new 的 方式
var robot = new Obeject();

// 用对象字面量的方式
var robot = {};

这里来看明显后面的方式看起来比较简洁,所以我们这里主要使用后者来创建我们的对象. 这时,我们需要给我们的 robot 赋予一些方法,例如他的代号code,他的生产序号number,他的攻击方式attackMode等属性,这时我们就可以这么来写.

// 第一种写法
var robot = {};
robot.code = 'r007';
robot.number = '666';
robot.attackMode = function (){
    // 拿小拳拳捶胸口
    ...
}

// 第二种写法
var robot = {
    code: 'r007',
    number: '666',
    attackMode: function(){
        // 拿小拳拳捶胸口
        ...
    }
}

这时我们访问我们的机器人对象属性时就可以通过以下两种方式来访问.

  • robot.code
  • robot['code']

但这时的我们肯定不会只满足制造一个机器人呀,这种机器人我们需要量产时,但是我们又不可能使用我们上面这种方法来制造多个机器人,这样写出来的代码量会有很多重复无用的代码,这时我们的工厂模式就应运而生.

// 这种方式太过于臃肿,你创建1000个机器人难道会像这样去声明1000个对象吗?
var robot = {
    code: 'r007',
    number: '666',
    attackMode: function(){
        // 拿小拳拳捶胸口
        ...
    }
}

var robotA = {
    code: 'r008',
    number: '777',
    attackMode: function(){
        // 拿小拳拳捶胸口
        ...
    }
}

工厂模式

工厂模式形象店来说就是我们自己创建一个模具,然后用这个模具来量产.

var createRobots = function(code,number){
    // 新建一个对象
    var robot = new Object();
    robot.code = code;
    robot.number = number;
    robot.attackMode = function (){
        // 拿小拳拳捶胸口
        ...
    }
    // 返回一个对象
    return robot;
}
// 示范的创建两个对象
var robotA = createRobots('r007','666');
var robotB = createRobots('r008','777');

这个时候看着很美好,但是渐渐地有些人发现了一些不同寻常的地方,那就是用工厂模式造出来的对象,我们没有办法去识别对象的类型,因为它们直接由 Object() 构造函数创建,原型链上只有 Object.prototype 对象.所以这里我们的构造函数也应运而生

构造函数

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次.在这里,就需要用到原型相关知识了.

这里如果还有对 new 的过程不是很了解的同学可以看下这里这篇文章

原型

当我们在创建我们的对象时,可以根据相应的需求,将一些属性或者方法挂载在我们原型对象的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(){
        // 那胸口给别人锤
        ...
    },
    ...
} 

原型链

到上面为止,我们造机器人已经搞得差不多了,但现在又来了一个新的需求,就是要我们去造一批新的机器人SSS,他是在上一篇机器人的本质上升级过来的,要求我们继承上一个机器人对象,这时我们就需要根据原型链来优雅的实现这一功能了,代码如下:

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面向对象该讲的都已经将得差不多了,如果那里有错误的地方,欢迎来指正,谢谢!!!

我的文章会同步更新发布在以下地方,欢迎大家关注或者star来了解我的最新消息!!!

未经允许,不准转载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 普通创建对象和字面量创建对象不足之处:虽然 Object 构造函数或对象字面量都可以用来创建单个对象,但这些方式有...
    believedream阅读 2,354评论 2 18
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,398评论 3 12
  • 本章内容 理解对象属性 理解并创建对象 理解继承 面向对象语言有一个标志,那就是它们都有类的概念,而通过类可以创建...
    闷油瓶小张阅读 839评论 0 1
  • 99天晨起感恩16 2017年1月27 感恩春节,大年三十万家团圆美满。 感恩阳光明媚的日子,2017年祝福我心想...
    树下的金矿阅读 115评论 0 0
  • 一点没有回家的感觉地就回家了。早起,收拾,推着箱子离开屋子,去坐地铁。和小谢约好了车站见。 后来表示两个人大写的迷...
    君子不欺公子方阅读 289评论 0 1