前端基础-JavaScript构造函数
第2章 构造函数
学习目标
- 构造函数语法
- 分析构造函数
- 构造函数和实例对象的关系
- 实例的 constructor 属性
- instanceof 操作符
- 普通函数调用和构造函数调用的区别
- 构造函数的返回值
- 构造函数的问题
2.1 构造函数
JavaScript 语言使用构造函数作为对象的模板。
所谓 ”构造函数”,就是一个普通的函数,只不过我们专门用它来生成对象(new 构造函数),这样使用的函数,就是构造函数;
它提供模板,描述对象的基本结构。
一个构造函数,可以生成多个对象,这些对象都有相同的结构。
function Person (name, age) {this.name = namethis.age = agethis.sayName = function () {console.log(this.name)}
}var p1 = new Person('Jack', 18)
p1.sayName() // => Jackvar p2 = new Person('Mike', 23)
p2.sayName() // => Mike
解析 构造函数代码 的执行
在上面的示例中,Person()
函数取代了 createPerson()
函数,但是实现效果是一样的。
这是为什么呢?
我们注意到,Person()
中的代码与 createPerson()
有以下几点不同之处:
- 没有显式的创建对象(没有使用字面量)
- 直接将属性和方法赋给了
this
- 没有
return
语句 - 函数名使用的是大写的
Person
而要创建 Person
实例,则必须使用 new
操作符。
以这种方式调用构造函数会经历以下 5 个步骤:
- 创建一个空对象,作为将要返回的对象实例。
- 将这个空对象的原型,指向构造函数的
prototype
属性。先记住,后面讲
- 将这个空对象赋值给函数内部的
this
关键字。 - 执行构造函数内部的代码。
- 返回新对象
function Person (name, age) {// 当使用 new 操作符调用 Person() 的时候,实际上这里会先创建一个对象// 然后让内部的 this 指向新创建的对象// 接下来所有针对 this 的操作实际上操作的就是刚创建的这个对象this.name = namethis.age = agethis.sayName = function () {console.log(this.name)}// 在函数的结尾处会将 this 返回,也就是这个新对象
}
构造函数和实例对象的关系
构造函数是根据具体的事物抽象出来的抽象模板
实例对象是根据抽象的构造函数模板得到的具体实例对象
实例对象由构造函数而来,一个构造函数可以生成很多具体的实例对象,而每个实例对象都是独一无二的;
每个对象都有一个 constructor
属性,该属性指向创建该实例的构造函数
反推出来,每一个对象都有其构造函数
console.log(p1.constructor === Person) // => true
console.log(p2.constructor === Person) // => true
console.log(p1.constructor === p2.constructor) // => true
因此,我们可以通过实例对象的 constructor
属性判断实例和构造函数之间的关系
注意:这种方式不严谨,推荐使用 instanceof
操作符,后面学原型会解释为什么
console.log(p1 instanceof Person) // => true
console.log(p2 instanceof Person) // => true
constructor 既可以判断也可以获取
instanceof 只能用于判断
2.2 构造函数存在的问题
以构造函数为模板,创建对象,对象的属性和方法都可以在构造函数内部定义;
function Cat(name, color) {this.name = name;this.color = color;this.say = function () {console.log('hello'+this.name,this.color);};
}
var cat1 = new Cat('猫', '白色');
var cat2 = new Cat('猫', '黑色');
cat1.say();
cat2.say();
在该示例中,从表面上看好像没什么问题,但是实际上这样做,有一个很大的弊端。
那就是对于每一个实例对象, name
和 say
都是一模一样的内容,
每一次生成一个实例,都必须为重复的内容,多占用一些内存,如果实例对象很多,会造成极大的内存浪费。
对于这种问题我们可以把需要共享的函数定义到构造函数外部:
function say(){console.log('hello'+this.name,this.color);
}function Cat(name, color) {this.name = name;this.color = color;this.say = say;
}
var cat1 = new Cat('猫', '白色');
var cat2 = new Cat('猫', '黑色');
cat1.say();
cat2.say();
这样确实可以了,但是如果有多个需要共享的函数的话就会造成全局变量(函数名)冲突的问题。
你肯定想到了可以把多个函数放到一个对象中用来避免全局变量(函数名)冲突的问题:
var s = {sayhello:function (){console.log('hello'+this.name,this.color);},saycolor:function(){console.log('hello'+this.color);}
}function Cat(name, color) {this.name = name;this.color = color;this.sayhello = s.sayhello;this.saycolor = s.saycolor;
}
var cat1 = new Cat('猫', '白色');
var cat2 = new Cat('猫', '黑色');
cat1.sayhello();
cat2.saycolor();
至此,我们利用自己的方式基本上解决了构造函数的内存浪费问题。
但是代码看起来还是那么的格格不入,那有没有更好的方式呢?
小结
- 构造函数语法
- 分析构造函数
- 构造函数和实例对象的关系
- 实例的 constructor 属性
- instanceof 操作符
- 构造函数的问题
前端基础-JavaScript构造函数相关推荐
- [前端基础] JavaScript 基础篇(下)
DOM 和 BOM DOM 指的是文档对象模型,它指的是把文档当做一个对象来对待,这个对象主要定义了处理网页内容的方法和接口.BOM 指的是浏览器对象模型,它指的是把浏览器当做一个对象来对待,这个对象 ...
- 前端基础JavaScript
JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECM ...
- 前端基础--JavaScript
一.JavaScript介绍 ● 虽然是java作为前缀,但java和javascript的关系,就像老婆和老婆饼之间的关系,没有一毛钱关系! ● 网景公司在Netscape2.0首先推出了JavaS ...
- 前端复习记录(前端基础 JavaScript)一
JavaScript(一) get请求传参长度的误区 误区:我们经常说get请求参数的大小存在限制,而post请求的参数大小是无限制的. 实际上 HTTP 协议 未规定 GET 和 POST 的长度限 ...
- 前端基础 JavaScript
JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.( ...
- 【前端】JavaScript构造函数
文章目录 概念 执行过程 返回值 原型与constructor 继承方式 原型链 其他继承方式(还没写) 参考 概念 在JS中,通过new来实例化对象的函数叫构造函数.实例化对象,也就是初始化一个实例 ...
- Web前端基础---JavaScript函数事件及其绑定DOM模型BOM模型
Day03 JavaScript JavaScript是一种属于网络的高级脚本语言,被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用 户提供更流畅美观的浏览效果.通常JavaScri ...
- [前端基础] JavaScript 进阶篇
封装 Ajax ajax 可以无需刷新页面与服务器进行通讯,允许根据用户事件来更新部分页面内容. readyStatus 的值: 0:未初始化 1:启动:已经调用open()方法,但尚未调用send( ...
- 前端基础-JavaScript
开发工具与关键技术:DW/浏览器 :简单使用js. 作者:刘佳明 撰写时间:2019年1月 18 日 前面已经随手写过了关于网页编辑的一些基础布局和标签的认识:这篇文章在这里为大家简单的介绍一下关于J ...
最新文章
- 个人理解卷积 池化 的用处
- MongoDB主从+php实现
- 广东移动携手远传技术 共建移动客服标杆
- Linux下为文件增加列的shell脚本
- JavaScript高级程序设计(第3版)非扫描版
- 使用ActionBar实现Tab导航(快速生成Tab样式)
- ORACLE1.10 - 一对多
- Spring MVC 实践笔记
- 【JPA 级联保存/级联删除】@OneToMany (双向) 一对多【转】
- 使用Delphi编写棋牌类游戏 – 设计篇(3)
- python从入门到精通 明日科技 电子书-python从入门到项目实践 (明日科技) 配套视频教程+源码...
- 「leetcode」C++题解:226.翻转二叉树,递归法与迭代法详解
- JSP教程第1讲笔记
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_01 File类_5_File类获取功能的方法...
- 【C语言】求两个数的最大公约数
- java创建二维码并赋予url链接
- SQL 数字和字符串互转
- win10便签常驻桌面_出奇的好用!聊聊被习惯性忽视的Win10“便笺”
- 软件测试的创新思维,解读测试设计
- 自己开发CMS系统还是使用成熟的CMS系统?