JavaScript 对象及对象的创建

前言

    即使不了解Javascript的设计原理和继承机制这些东西的时候,我们依然能很好的使用Javascript去设计前端页面及功能。

    这得力于传统jquery时的前端开发我们把大部分的业务逻辑封装在后台,前端代码的逻辑性大大降低,我们只需要使用一点点j和ava语法类似的知识就能写出所需的javascript代码。

    这时候我们不需要考虑继承,不需要考虑复杂的封装,甚至连this关键字我们都用的极少。但在接触了react,vue这些前端框架之后就有必要详细的了解与学习Javascript了,Javascript已经变成一个独立于后端的完整的前端框架的一个基础。

对象及对象的创建

    Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分。我们举几个例子,一下的都是对象。

    这些基础的数据类型也是对象但是不在本章的讨论访问之内。

这两行都是等价的,都生成了一个名为fun1的(函数)对象。


    这是我们比较常见的对象方式,用大括号的方式创建对象,采用键值对的方式描述对象属性。

    这个对象的结果其实和第三个对象是一样的都是可以用{}来表述的。

    我们可以很清楚的看出这都是对象,完全没有类的概念,我们最后一个例子里的Object是类么?不,不是的。接下来就要说明一下对象的创建方式。

顺便给大家推荐一个裙,它的前面是 537,中间是631,最后就是 707。想要学习前端的小伙伴可以加入我们一起学习,互相帮助。群里每天晚上都有大神免费直播上课,如果不是想学习的小伙伴就不要加啦。

    对象的创建方式只有一种,那就是

    所以我们很清楚了,Object是一个构造函数(对象)。

    这么设计的原因是因为当初javascript的设计者并不打算引入"类"(class)的概念,因为一旦有了"类",Javascript就是一种完整的面向对象编程语言了,这好像有点太正式了,而且增加了初学者的入门难度。不过他在设计创建对象的方式上却借鉴了C++和java的语法,引用了new关键字,但是javascript是没有类的?那么new后面跟着是什么呢?它发现java与C++对象的创建都必须执行构造函数(constructor),于是乎他就做了简化的设计,在Javascript语言中,new命令后面跟的不是类,而是构造函数。

    所以以上四种范例其本质上都是javascript通过new 构造函数的方式隐式或显式帮我们创建的。我们先详细的了解一下构造函数的创建方式再细说范例中是如何隐式创建的对象。

构造函数 construct

示例:

    7丨console.log(zs); //[object Object]  

{[functions]: , __proto__: { },age: 23,name:"zhangsan",sex: "man"}

    可以看到我们根据man构造函数创建了一个对象zs,对象有name,age和sex 属性。在这里面我们可以清楚的看到构造函数给对象设置属性的方式是this关键字,this关键字动态指向的是创建的对象(关于this的其它问题会另起一章介绍),this关键字后跟着的属性或方法就是该对象的属性或方法。但是如果构造方法有返回值,那生成的对象就是构造方法的返回值了,所以大家在写构造方法时要特别注意,示例如下:

    看到zs的值变成了{info:‘error’},所以写构造函数的时候最好也不要写返回值。但是我发另一很奇怪的情况,示例如下

丨:"zhangsan",sex: "man"}

    我们看到如果返回的是基本类型,整型,字符串类型等的那构造函数还是生效了,这另我十分费解。不过只要记住在我们写构造函数时不去写返回值也就能规避这种问题。

    构造函数创建的方式也不是完全完美的,比如看下面的示例中的sex属性,如果通过man构造函数创建出来的对象sex都固定是“man”,那每个对象都要分配内存来存储sex属性是不是有些浪费呢?或者就是有些属性要给所有对象共用的呢?比如对象的方法,完全不需要随着对象变化,该如何处理?

    为了解决这个问题,javascript为构造函数(函数类型对象)提供了prototype属性。

prototype属性

    prototype只能用于函数对象,如果你给其它非函数对象增加prototype属性,执行器会报出该对象无prototype属性错误。

    我们先来一个示例来看prototype如何使用

    我们看到构造函数通过prototype属性增加的属性或方法是给所有对象共享的。我们把那些需要共享的方法和属性放在prototype属性里,那些不需要共享的属性和方法,就放在构造函数里面。

    而实现过程是这样的,当实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。

顺便给大家推荐一个裙,它的前面是 537,中间是631,最后就是 707。想要学习前端的小伙伴可以加入我们一起学习,互相帮助。群里每天晚上都有大神免费直播上课,如果不是想学习的小伙伴就不要加啦。

    我们再看一个示例

    我们看到只有通过prototype属性修改sex对象才能更新全部对象的sex属性,而单单修改某个对象的sex属性是无法全局修改的,对于这个我不知道是如何实现的,有知道的不吝赐教。

    我们再看一个示例

    这个示例只是prototype下属性的修改方式改为对整个prototype属性的对象进行设置。这种方式可以么?可以,而且修改成这样对上一个示例的输出完全没有影响。但是个人还是不推荐这种方式,因为prototype属性还有一个特别的方法constructor。

constructor

    我们先介绍下constructor属性

constructor属性是指向构造方法的引用,也就是说如下两行代码是等价的。

    看起来好像没什么用,但是我们知道prototype可以把自己的属性传递给对象的。也就是说我们可以通过constructor来比较两个对象是不是同一个构造器的实例,示例如下:

    所以通过man.prototype={…}的方式设置共享属性会破坏constructor属性。虽然好像破坏了在我们的使用中不会产生任何影响,但我们还是要知道有这个属性的存在及prototype的作用。

    prototype还有一些其他方法,但是通过man.prototype={…}方式是破坏不了,只是因为所有对象的这些方法都是一致的,比如isPrototypeOf,hasOwnProperty方法,提供几个示例,就不详述了。

    isPrototypeOf 示例是不是来自该构造函数

    hasOwnProperty 每个实例对象都有该方法,用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性

    我们再看一下最开始我们说的那个问题,所有的对象生成本质上都是通过构造函数生成的。查看的方法很简单,我们知道每个对象都有一个constructor方法,我们只要输出每个对象的constructor方法就能找到他的构造函数。

其它问题

    我们说了构造函数,什么样才能算是构造函数呢?所有的函数都可以是构造函数,所有的函数也只有函数可以拥有有prototype属性。而函数也是对象,如上面例子的fun1函数,它也是由Function()构造函数生成的,fun1是函数对象,你可以把fun1当对象用,给他设置属性,方法都是完全没问题的,但是fun1.prototype设置的属性也只能给new fun1()生成的对象使用,不能混淆了。

    有说javascript的继承机制是依靠prototype属性(原型链{prototype chain}模式)来实现的,但是因为通过prototype设置“父对象”的属性和方法,只能变成“继承”共享的属性和方法,每个对象自己私有的属性和方法是无法继承的,还是有一些不一样的。而且说是共享只能说是统一赋值,我们通过对象去修改prototype提供的属性并不会影响其他对象的该属性。说是继承但是不太一样。

    在理解javascript的对象及对象的创建时要牢记两点,一个是javascript内(几乎)所有的都是对象,并且对象都有构造函数和一些默认方法。比如我有时忘记这两件事,写一些奇怪的范例时就很懵逼,为什么会出现这个结果。如我常忘记prototype属性指向的也是对象,对象也就会有constructor,isPrototypeOf 等这些方法。

作者:spongeboblz  

来源:CSDN                                        

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

推荐阅读更多精彩内容

  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 2,107评论 0 6
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,122评论 0 21
  • 面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的慨念,而通过类可以创建任意多个...
    threetowns阅读 876评论 0 4
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,421评论 3 12
  • 下午站上体重秤看到数字的时候简直要惊跳起来,卧槽又胖了几斤! 想到健身卡已经办了一个月了,趁春暖花开狗熊撒欢的季节...
    猫偲阅读 401评论 6 4