JavaScript学习之旅-12( 原创 )
在上一篇文章中,主要学习了JavaScript中的Date对象、正则表达式、Json、浏览器对象。这一篇我们主要深入学习探索JavaScript中的对象以及构造函数的说明和使用。
我们知道,在Java这门面向对象建模的计算机语言中,创建对象(新建一个Class,肯定是直接或者间接继承Object)、创建完毕之后接着使用对象(使用对象内部封装的函数完成开发需求,也就是new 对象,使用对象内的方法,也称对象的实例)是这们语言的灵魂和基础。不过,在JavaScript中,这个概念需要改一改。JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。实际上JavaScript对每个创建的对象都会设置一个原型去指向它的原型对象。
继承,是Java这门语言的特征之一,子类继承父类的目的是,子类可以吸收父类的数据属性和行为,并能扩展新的能力。那么,在JavaScript中,也有一种类似继承拓展的能力,我们首先定义一个对象:
假设我现在想和Java一样,想实现类似继承的功能,这个该如何去做?这个时候,我们可以首先定义一个对象,然后使用关键字 __proto__ 去完成操作,写法如下:
其中,红色的矩形为写法以及关键字,蓝色箭头代表“父类”,然后测试下结果:
可以看到,我们使用关键字 __proto__ 之后,红色矩形内的名字以及成功被我们修改成 Tom 了,且 newCooker对象也成功使用了“父类”里面的play字段的函数。
但是一般不要直接用obj.__proto__去改变一个对象的原型,并且,低版本的IE也无法使用__proto__。解决办法如下:可以使用Object.create()方法,这个方法可以传入一个原型对象,并创建一个基于该原型的新对象,但是新对象什么属性都没有,因此,我们可以编写一个函数来创建想要“继承父类的子类”。
那么我们把上面的代码用函数返回对象的方式改一下,就有了以下的代码:
关于继承的这一特点,会在下面的一篇文章专门讲述。
概念一:向上查找
我们首先复习回顾下JavaScript中对象的基本写法:
获取对象内的属性值,我们知道是用 obj.xxx 去获取一个对象的属性。那么这个获取对象属性值的操作是如何执行的?JavaScript首先在当前对象上查找该属性,找到了该属性值就返回,如果没有找到,就到其原型对象上一级找。如果还没有找到,就一直向上直到Object.prototype对象。
如果Object也没有找到,就返回undefined。
别忘了,JavaScript中,函数也是一个对象。这个跟Java有很大的差别(因为Java中函数的返回值可以是void)。所以,JavaScript首先在当前函数对象上查找该属性,找到了该属性值就返回,如果没有找到,就到其原型对象上一级(也就是Function.prototype)找。如果还没有找到,就一直向上直到Object.prototype对象。
如果Object也没有找到,就返回undefined。
所以,函数对象和普通对象的执行顺序都是一样的,自己要是没有就向上找,如果上层也没有这个对应的属性,就会undefined。
概念二:构造函数
我们知道,Java的构造函数主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。那么,JavaScript中的构造函数是什么?
JavaScript可以用构造函数的方法来创建对象。它的用法如下:
首先这是一个普通函数,但是在JavaScript中可以使用关键字new来调用这个函数,并返回一个对象(按照约定,构造函数首字母应当大写,而普通函数首字母应当小写,这里为了展示方便就用小写,后面还是需要严格按照书写规范进行书写)。如果不写new,这就是一个普通函数,它返回undefined。但是,如果写了new,它就变成了一个构造函数。
用new 函数()创建的对象,理论上从原型上获得了一个constructor属性,它指向函数本身(这里就是 constructorFun )
通过实践得知,构造函数的constructor属性原则是一样的。
还有一种情况:
如果我们通过new 构造函数创建了很多对象,这些对象的内部函数实际上只需要共享同一个函数就可以了,这样可以节省很多内存。
要让创建的对象共享公共的函数,根据对象的属性查找原则,我们只要把公共函数移动到new 出来的对象上一层就可以了(Java中叫抽取公共代码放到父类,也可以用构造代码块去实现),那么上面的代码我们可以改成这样:
构造函数的进阶用法:
如果一个函数被定义为用构造函数去创建对象,但是使用时我们忘记了写 new 怎么办?
为了规避这种情况,我们可以从书写规范去入手,上面也提到过构造函数首字母应当大写,而普通函数首字母应当小写。然后还有一种比较好的方式,就是参考Java中的做法,将实例化对象的操作,放在一个函数里面,这样通过调用这个函数就可以间接的给我们完成new对象的工作了。代码如下
首先,蓝色方框内,是一个构造函数,里面是具体的属性
然后我们把new对象的过程放在了图中的红色方框,
绿色方框就是调用new对象的函数,将参数传递进去,完成赋值操作,然后打印。
这样写的函数有以下优点:一是不需要new来调用,二是参数非常灵活,可以不传也可以传。当然也比较推荐这种写法。
本篇文章主要学习的是关于对象的深入分析以及构造函数的说明和使用。本章的基本内容就结束了。
未完待续。。。
如果这篇文章对你有帮助,希望各位看官留下宝贵的star,谢谢。
Ps:著作权归作者所有,转载请注明作者, 商业转载请联系作者获得授权,非商业转载请注明出处(开头或结尾请添加转载出处,添加原文url地址),文章请勿滥用,也希望大家尊重笔者的劳动成果。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
深入理解虚拟机之虚拟机类加载机制
《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版》读书笔记与常见相关面试题总结 本节常见面试题(推荐带着问题阅读,问题答案在文中都有提到): 简单说说类加载过程,里面执行了哪些操作? 对类加载器有了解吗? 什么是双亲委派模型? 双亲委派模型的工作过程以及使用它的好处。 前言: 代码编译的结果从本地转换为字节码,是存储格式发展的一小步,却是编程语言发展的一大步。 1 概述 上一节我们已经知道了类文件结构,在class文件中描述的各种信息最终都需要加载到虚拟机中之后才能运行和使用。 那么虚拟机是如加载这些class文件呢?class文件中的信息进入到虚拟机后会发生什么变化呢? 1.1 虚拟机类加载机制的概念 虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化。最终形成可以被虚拟机最直接使用的java类型的过程就是虚拟机的类加载机制。 1.2 Java语言的动态加载和动态连接 另外需要注意的很重要的一点是:java语言中类型的加载连接以及初始化过程都是在程序运行期间完成的,这种策略虽然会使类加载时稍微增加一些性能开销,但是会为java应用程序提供高度...
- 下一篇
struts2 常用标签总结
1. 使用Struts2的常用逻辑标签 1.1 property标签 功能说明 获取对象的属性值,目标对象默认位于ValueStack栈顶 标签属性 名称 必选 类型 说明 value no Object 对象的属性名称,默认直接输出 ValueStack 栈顶对象 default no String 默认值,如果 value 为 null 则输出此值 escape no Boolean 是否进行html 转义,默认为 true escapeJavaScript no Boolean 是否进行JavaScript 转义,默认为 false eg: <s:property value="user.userName"/> 1.2 if-elseif-else标签 功能说明: 替代Java语法中的if/else 标签属性: 名称 必选 类型 说明 test yes Boolean 表达式,决定是否显示if/else if 标签体的内容 eg: 欢迎${user.name} , <s:if test="user.role == 'admin'">系统管理员</s:...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果