面向对象与原型(二)

楔子

问题

在 java 中,首先定义一个 class,然后 new 出该 class 的实例,那么无论 new 多少次,新出现的类永远都具有 class 中定义的属性。

但 js 中不一样,js 中为某个对象新添加的属性,不会出现在新对象中。如下:

var o1 = {}
o1.name = 'o1.name'

var o2 = {}
alert(o2.name)

首先为 o1 创建 name 属性,但这个属性并没有被带到 o2 中,如果 o2 也想具有与 o1 一样的属性,就需要将 o1 的属性定义全部重写一遍。这就导致了一个问题 想要创建一个类似的对象,就需要写很多重复代码

假设有对象 A,现在想创建一个跟 A 只有一个属性不同的对象 B。按上述思路,我们需要重新创建一个 B 对象,然后将 A 、B 对象共用的属性与方法赋值给 B,代码繁琐。

工厂方法模式

为解决上述问题,可以使用工厂方法模式。

function createObj(){
    var d = new Object();
    d.h='h';
    return d;
}

通过上述方法产生的对象都会具有 h 属性。但由于工厂方法具有封装性,外界使用者根本不知道产生的对象是哪一个类的实例,也无法修改返回对象对应的类,因此,使用者可能没办法调用某些类特有的方法。

例如使用 createObj 方法产生对象后, 想调用 getFullYear() 方法是不可能的。因此 Object 对象没有 getFullYear() 方法。如果想使用 getFullYear() 就需要改成如下代码:

function creatObj2(){
    var d = new Date();
    d.h='h';
    return d;
}

这会有几个问题:1,使用者不能修改工厂方法里的代码;2. 即使修改了,也没有办法保证工厂方法能兼容所有的类,类的个数无限,不可能为每一个类创建一个工厂方法。

构造函数

  1. 构造函数也是函数,也可以直接调用;每一个函数都可以转成构造函数,从而可以创建实例

  2. 与 new 关键字结合时,普通函数会转为构造函数,进而创建出一个对象,该类的类名就是构造函数的方法名

    var o = function(){
        this.age = arguments[0]; // this 指代的是新创建出来的对象
    }
    var oo = new o('age'); // 与 new 关键字结合,转为构造函数,进而创建一个实例
    alert(oo.age)
    alert(oo instanceof o) // true
    
    o('直接调用'); //直接调用时,this 指代的是 window
    alert(window.age+",from window") // 所以 window.age 输出的是 ‘直接调用’
    
  3. 由于 this 指代的是当前对象,所以在构造函数中的 this 指的就是新创建的对象

    function Demo(){
            this.m = function(){
            alert('this is m ')
        }
    }
    
    var o = new Object();
    Demo.call(o)
    o.m()
    

    如果不调用 Demo.call() 就没办法直接调用 o.m() ,因为 Object 类中没有方法名为 m 的方法。
    调用 call 方法后,相当于在 o 对象中运行了一次 Demo 方法,而其中的 this 指的就是 o 对象,所以 o 对象中已经具有了 m 方法。

  4. 与工厂方法相比,构造函数有如下优点:

    • 没有 new Object()

    • 直接将属性赋值给 this ,而不是赋值给一个 Object 对象

    • 不需要直接返回一个对象。

    • 返回的对象不但 instanceof Object ,而且还 instanceof 构造函数对应的类。

  5. 构造函数实质上与工厂方法一样,只不过 new Object() 与 return 语句是在后台进行。构造函数算是一个改良后的工厂方法

  6. 一般来说,构造函数首字母大写,而普通函数不需要。

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

推荐阅读更多精彩内容