深入了解javascript(三)——面向对象与原型

面向对象是js最难弄懂的一部分,我在看了《Javascript高级程序设计》之后还看了李炎恢老师关于面向对象与原型的讲解,算是理解了,在此做下笔记,仅为以后的个人学习作参考。先从创建对象逐步剖析

Object构造函数创建多个实例

这种Object构造函数创建多个对象,容易造成代码冗余,所以有工厂模式的出现

工厂模式创建对象,就是普通函数的创建

但是工厂模式没有解决多个对象识别的问题,即怎样知道一个对象的类型,怎样体现呢

工厂模式无法解决对象识别的问题

很明显,box2是createObject的对象,但三个提示框的结果都是true,只知道它们都是object,但不知道是谁的对象,所以就有了构造函数创建对象模式的出现

构造函数很好地接解决了工厂模式无法识别对象的类型的问题


注意几点: 构造函数没有显式地创建对象;直接将属性和方法赋给了this对象;要创建实例,必须使用new 关键字;将构造函数的作用域直接付给这个对象(this也就指向了这个新对象);构造函数的首字母必须大写,比如例子中的Box,Box1;

构造函数的调用

构造函数的问题(不同实例的同名函数不相等)

创建两个完成同样任务的函数没有必要,但我们可以这样来解决

我们把sayName()函数的定义转移到构造函数外部,在构造函数内容,我们把sayName属性设置成等于全局的sayName函数,box1、box2对象就共享了在全局作用中定义的同一个sayName函数,这着实解决了两个函数做同一个事情。但是新的问题又来了,sayName是全局函数,如果对象需要用到多个函数,那么就要定义多个全局函数,这样这个自定义的引用类型没有封装性可言。我们可以通过原型模式来解决

使用原型的好处:让所有对象实例共享它的属性和方法

理解原型对象:只要创建了一个新的函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向原型对象。在所有默认的请款下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。就拿上面的例子来说,Box.prototype.constructor指向Box

这张图是《Javascript高级程序设计》上面,实例对象和属性方法的名字不一样而已,、
红线标注的返回true

用原型对象isPrototype()方法测试了Box,因为它们的内容都有一个Box.prototype的指针,因此都返回了ture

每当代码读取某个对象的某个属性时,都会从实例开始,如果找到了话就返回,没有找到则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。

可以通过对象实例访问原型的值,但是不能通过对象实例重写原型中的值,但是可以通过delete完全删除实例属性的值,从而使对象实例访问原型的值

通过delete删除实例属性


hasOwnProperty()可以检测一个属性是存在实例中还是存在原型中,存在实例中返回true

原型与in操作符(两种使用情况:单独使用和在for-in循环当中)

还有个值得注意的是hasprototypeProoerty()是与hasOwnprotery刚好相反

使用字面量来创建原型

原型的动态性


关于这里我是有个问题的,难道说原型要写在创建实例对象之前,才不会说是切断实例与原型的关系

原型对象的问题:也是原型对象的优点,即最大的问题是由共享属性所导致的。然而,如果原型当中包含引用类型的属性来说,问题就比较突出了

这里还是有个问题

两张图的区别是一个通过box1.family.push(),另一张是通过box1.family = [],结果不一样,引用类型.属性.方法可以重写原型当中的值,但是引用类型.属性只能操作但是不能修改原型中的值,针对这些问题,所以有组合使用构造函数和原型模式的出现

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

构造函数+原型实在ECMAScript当中最广泛、认同度最高的一种创建定义类型的方法

动态原型模式


红线标注的部分说明在run()方法不存在的情况下执行

注意:使用动态原型模式,不能使用对象字面量重写原型;如果在创建实例的情况下,那么就会切断现有实例与原型之间的关系

寄生构造函数模式

 

改函数的作用是仅仅是封装创建对象的代码,然后在返回新创建的对象。关于寄生构造函数模式:返回的对象与构造函数或者构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的蚃没有什么不同。为此,不能依赖instanceof操作符来确定对象类型。不建议使用这种模式

稳妥构造函数模式

咋一看,好像跟寄生构造函数没有什么不同。但还是有两点不同的,一是新建对象的实例方法不引用this;二是不使用new操作符调用构造函数,Box里面的属性是似有,除了run方法之外,没有其他的办法访问name和age属性,因此稳妥构造函数是比较安全的


继承

继承是OO(面向对象)语言一个重要的概念。许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承则继承方法签名,函数没有签名,因为ECMAScript只支持实现继承,而且实现继承主要是依靠原型链来实现的

原型链:利用一个引用类型继承另一个引用类型的属性和方法。构造函数、原型和实例的关系:每个够走啊函数都有一个原型独享,原型对象都包含一个指向构造函数的指针,而实例都柏寒一个指向原型对象的内部指针。

原型链继承

注意:有时我们需要在子类型中重写超类型的某个方法,或者需要添加超类型中不存在的某个方法,但不管怎样,给原型添加方法的代码一定要在替换原型之后

还有一点,通过原型实现继承时,不能使用对象字面量创建原型方法,因为这样会重写原型链

原型链的问题:1、包含引用类型值得原型属性会被实例共享(之前的解决办法是使用构造函数+原型,即引用类型值放在构造函数当中而不是原型当中),通过原型链继承,被继承的原型会成为继承的原型的一个实例,进而原先的实例属性会成为另外一个原型的实例属性了)

2、在创建子类型的实例时,不能像超类型的构造函数中传递参数

借用构造函数实现继承

解决了单独使用原型链的两个问题:借用构造函数引起引用类型没有被共享同时还解决了子类型向超类型传参的问题

借用构造函数的问题:方法都在构造函数当中定义,函数复用就无从谈起了。而且,在超类型的原型中定义的方法,对子类型而言是不可见的

推荐:组合继承(原型链+构造函数)

组合继承避免了原型链和构造函数的缺陷,融合了它们的优点

原型式继承,有点难以理解,不想作过多的解释

寄生式继承(构造函数+工厂模式,下面写错了)

使用集成式继承为对象添加函数,会由于不能做到函数复用而降低效率;这一点与构造函数模式类似

(常用)寄生组合式继承

所谓寄生式继承,通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其基本的思路是:不必为了制定子类型的原型而调用超类型的构造函数,我们所需要的无非就是hi超类型原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果制定给子类型的原型。

寄生组合式继承的基本模式

结语,在面向对象与原型通过结合书本和视频的方式去学习,本身原型和原型链是js的重点难点。希望在接下来的组件化开发当中能够有效地运用起来,不然一切都是纸上谈兵

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

推荐阅读更多精彩内容