慕妍 發表於 2022-5-19 16:14:00

JS与ES6高级编程学习笔记(三)——JavaScript面向对象编程

<h1>一、概述</h1>
<p>面向对象程序编程(Object-oriented programming,缩写:OOP)是用抽象方式构建基于现实世界模型的一种编程模式,JavaScript是一种基于对象(object-based)的语言,支持面向对象编程与函数式编程,但JavaScript的面向对象与其它的面向对象语言有较大差异,ECMAScript中没有类的概念,所以对象也有所不一样。</p>
<p>本章主要让讲解JavaScript中对象、原型与函数间的关系及面向对象编程相关内容。</p>
<h1><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">二、对象</span></h1>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript中的一切都是对象,万物皆为对象,函数也是对象,要学习JavaScript面向对象编程需要先理解对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">对象的定义是无序属性的集合,其属性可以包含基本值、对象或函数。通俗说对象就一个键值对集合,键是名称,值可以是数据或函数。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">2.1、创建对象</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript中有大量的内置对象,为开发提供了方便,但面向对象编程我们需要将现实世界抽象成自定义的对象,这里介绍多种对象的创建方式。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(1)、对象字面量 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">对象字面量是一种最直接最简单的对象创建方式,一个对象字面量就是包含在一对花括号中的零个或多个"键/值"对。对象字面量可以出现在任何允许表达式出现的地方。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //空对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj1={}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //对象中的属性,如果属性名有空格需要使用引号 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj2={name:"foo",age:19,"nick name":"bar"}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //对象中的方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj3={ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> 'price':99, //属性名可以用引号与可不用 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> inc:function(){ //方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> this.price+=1; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj3.inc(); //调用方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj3.inc(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(obj3.price); //访问属性,输出101 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">对象中可以包含的内容是数组、函数、对象、基本数据类型等,他们间还可以嵌套或混合出现,数组中可以有对象或函数,对象中可以有数组或函数。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //定义数组 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var users = [{name: "jack"}, { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> name: "lucy", //常量 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> hobby:["读书","上网","代码"], //数组 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> friend:{name:"mark",height:198,friends:{}}, //对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> show:function(){ //函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("大家好,我是"+this.name); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }]; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //对象中的this是动态的,指向的是调用者 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> users.show(); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行后输出:大家好,我是lucy </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(2)、通过new创建对象 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">对象字面量创建非常直接,但不能复用属性或方法,使用new运算符创建并初始化一个对象,new后面接一个构造函数(constructor),调用时默认返回this对象。new 关键字会进行如图3-1四个步骤的操作。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161327460-1204810201.png" alt=""></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //使用内置构造函数创建对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj1=new Object(); //创建一个空对象,等同{}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj1.name="mark"; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj1.show=function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("我叫"+this.name); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var arr1=new Array(); //创建一个数组对象,等同[] </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj1.show(); //调用obj1中的show方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //使用自定义构造函数创建对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function User(name){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> this.name=name; //添加属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> this.show=function () { //添加方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("我叫"+this.name); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var rose=new User("rose"); //创建User对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var jack={}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> User.call(jack,"jack"); //借调构造函数User,完成对象的初始化 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> rose.show(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> jack.show(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(rose instanceof User); //rose是否为User类型的实例 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(rose instanceof Object); //rose是否为Object类型的实例 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(jack instanceof User); //jack是否为User类型的实例 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(jack instanceof Object); //jack是否为Object类型的实例 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-2所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161327692-1325310776.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-2 通过new创建对象示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果中可以看出通过call方法借调构造器生成的对象依旧是Object类型,并不是User类型,这是因为jack这个对象是通过字面量直接创建的,call只是调用构造函数初始化了这个对象。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">2.2、使用对象</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">访问对象主要包含取值、修改、删除、迭代操作。取值使用点运算最多,但遇到key为关键字或含有空格时也可以使用"对象名"的方式完成,示例代码如下: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //定义对象字面量 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj1={name:"foo",age:19,"nick name":"bar"}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //取值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(obj1.name); //等同于obj1["name"],点运算取值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(obj1["nick name"]); //因为key中含有空格这里只能如此访问,字符串索引取值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //修改 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj1.age=18; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //删除属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> delete obj1.name; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //枚举,将对象中的key逐个取出(无序) </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> for(var key in obj1){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(key+"-&gt;"+obj1); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-3所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161327932-1435411205.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-3 访问对象示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">通过示例可以看出delete后对象中的成员就被删除了,迭代输出结果中并没有name,delete运算符只能删除自有的属性,不能删除继承的属性,删除成功后会返回是否删除成功的布尔类型值(true/false);另外要注意的是迭代默认是无序的,并不会按照对象中属性的顺序输出。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">2.3、原型及关系</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">在JavaScript中关于原型(prototype)、原型链、__proto__、Function、Object等内容是较难理解的,因为它与经典的面向对象(如Java与C++中面向对象的概念)存在较大的差别。只有理解了这些概念与特性我们才能更好的掌握JavaScript的面向对象核心。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>prototype(原型)</strong>:函数中的一个属性,指向该构造函数的原型对象(原型对象用于实例共享属性和方法),任何函数都拥有该属性。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>__proto__:</strong>对象中的一个非标准内部属性,指向构造函数的原型对象,在ECMA-262第五版中被称为[],且没有标准的方式能访问到,__proto__为浏览器支持属性;作为对象的内部属性,是不能被直接访问的。为了方便查看一个对象的原型,Firefox和Chrome中提供了"__proto__"这个非标准的访问器(ECMA引入了标准对象原型访问器"Object.getPrototype(object)")。任何对象都拥有该属性。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>constructor:</strong>原型对象中的一个属性,指向该原型对象的构造函数; </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">如图3-4所示我们先来看看函数、对象、原型、Object与Function关系之间的关系图。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161328393-2138581707.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-4 函数、对象、原型、Object与Function关系图 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(1)、任何函数是对象也是构造器(constructor)</strong>。函数与构造器在定义上没有任何区别,习惯把构造器名称的首字母大写。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(typeof Cat); //function </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Cat instanceof Function); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Cat instanceof Object); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var mycat=new Cat(); //调用构造函数,创建对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(mycat instanceof Cat); //true </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果可以看出Cat是一个函数也是一个对象,函数是一个特殊的对象,Function构造了所有函数(function),函数创建了对象,Function自己创建了自己。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(2)、任意函数都有prototype属性</strong>,其属性值将被作为原型赋值给所有对象实例(也就是设置实例的__proto__属性)。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {} //定义函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Cat.prototype); //输出函数的原型 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function foo(){}; //定义函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(foo.prototype); //输出函数的原型 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype={name:"foo"}; //修改函数的原型,默认为Object类型的对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var mycat=new Cat(); //创建Cat类型的对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(mycat.name); //从原型链上获得name属性 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-5所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161328665-1721891326.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-5 访问对象示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(3)、JavaScript中所有的对象(函数也是对象)都包含__proto__(原型)属性(非标准)</strong>,都指向其构造器的prototype。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {}; //构造函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var o={}; //对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var fun=new function(){}; //函数表达式 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Cat.__proto__); //获得对象的原型(非标准) </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(o.__proto__); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(fun.__proto__); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //获得对象的原型(标准) </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.getPrototypeOf(fun)===fun.__proto__); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var mycat1=new Cat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var mycat2=new Cat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //对象的原型指向其构造器(函数)的原型对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(mycat1.__proto__===Cat.prototype); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //同一个构造器的对象共享原型 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(mycat2.__proto__===Cat.prototype); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-6所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161328936-1182587518.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-6 所有对象都含有原型示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">Object.getPrototypeOf(对象)方法可以获得对象的原型,这是推荐的标准做法,从示例中可以看了任意对象都包含原型,同一个构造器的实例共享一个原型,可以达到继承的目的。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(4)、函数的__proto__都指向Function.prototype,它是一个空函数(Empty function)。 </strong></span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {}; //构造函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(typeof Function.prototype); //function,注意这里不是Object </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Function.prototype===Cat.__proto__); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function foo() {} //函数声明 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Cat.__proto__===foo.__proto__); //true </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">函数都是Function的实例,所以函数的原型__proto__指向Function.prototype,这里非常特别的是它不是一个对象而是一个空函数。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(5)、函数都是由Function构造出来的,Function自己构造了自己,Object是由Function构造出来的</strong>,Function是构造器。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {}; //构造函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //函数都是由Function构造出来的 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Cat instanceof Function); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //Function自己构造了自己 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Function instanceof Function); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //Object是由Function构造出来的 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object instanceof Function); //true </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(6)、对象的最终原型对象都指向了Object的prototype属性,Object的prototype对象的__proto__属性指向NULL。 </strong></span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {}; //构造函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var mycat=new Cat(); //构造Cat类型的对象mycat </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(mycat); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(mycat.__proto__.__proto__===Object.prototype); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.prototype.__proto__); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-7所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161329184-1021518756.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-7 原型链示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果可以看出mycat是Cat构造出来的对象,所以mycat的__proto__指向Cat的prototype对象,Cat的prototype对象是Object构造出来的对象,所以Cat的原型__proto__指向Object的prototype对象,而Object的prototype对象的原型__proto__最终则指向null,到这里搜索资源就结束了,其实这就是原型链,JavaScript也就是通过该方式实现继承的,图3-8是用较直观的方式表现他们之间的关系。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161329505-54175536.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-8对象的最终原型示例 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(7)、所有prototype原型对象中的constructor属性都指向其构造器。 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(8)、原型对象prototype中的成员是所有被创建对象共享的。 </strong></span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {};//构造函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype={name:"foo"}; //定义Cat的原型对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat1=new Cat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat2=new Cat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.name===cat2.name); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.name,cat2.name); //foo foo </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //修改构造函数中原型对象的name属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype.name="bar"; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //所有Cat的实例都被影响 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.name,cat2.name); //bar bar </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">示例中cat1与cat2都是Cat的实例,那么cat1与cat2的原型属性__proto__指向了Cat的prototype对象,该对象是cat1与cat2共享的,当修改原型对象时所有实例都受到影响。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">这里需要注意的是如果我们在cat1中添加name属性如下所示: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cat1.name="min"; //cat1对象中添加属性name </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.name,cat2.name); //min bar </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">这里并不是访问原型对象中的name属性,而是向cat1中添加一个新的属性name,因为按就近原则cat1.name的优先级高于Cat.prototype中的name属性所以输出时选择了自己的属性name,可以通俗的理解cat1有两个name属性。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">(9)、<strong>对象在查找成员时先找本对象本身的成员,然后查找构造器的原型中的成员</strong>,一步一步向上查找,最终查询Object的成员,这就是原型链。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">使用prototype可以扩展内置对象,虽然JavaScript内置对象已非常强大,但面对复杂多变的开发需求肯定有不足的地方,这时可以通过修改prototype实现扩展功能。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">这里扩展String构造函数,返回字符的长度,一个中文算2个长度。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //如果不存在则扩展 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> if (!String.prototype.lengthPro) { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //在String的原型中添加LengthPro函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> String.prototype.lengthPro = function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return this.replace(/[^\x00-\xff]/g, "**").length; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("你好tom!".lengthPro()); //8 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("你好tom!".length); //6 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">lengthPro函数是通过正则将中文替换成2个字符串然后再调用内置的length达到目的的,这里的this就是字符串实例。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">2.4、对象的成员</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript中的对象的成员一般可以分成三类,分别是实例成员、原型成员与静态成员。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">实例成员是对象自身的原生成员,不来自原型与原型链;静态成员属于构造器本身,调用时使用"构造器名称.成员名"的方式进行,使用该构造器创建的对象不会继承该成员;原型成员是所有被创建实例共享的,创建对象时自动继承给每一个对象。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> this.show=function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("Cat的实例成员"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype.show=function(){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("Cat的原型成员"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.show=function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("Cat的静态成员"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat=new Cat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cat.show(); //Cat的实例成员 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.show(); //Cat的静态成员 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> delete cat.show; //删除实例成员show函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cat.show(); //Cat的原型成员 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从上面的代码可以看出当原型成员与实例成员冲突时实例本身的成员优先级要更高一些。</span></p>
<h1><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">三、Object</span></h1>
<ol>
<li>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">Object是一个非常重要的内置函数对象,所有对象最终都源自Object,其他所有对象都继承 Object,都是Object的实例。调用Object构造函数可以创建新对象,Object原生方法分成两类:Object原型方法和Object静态函数。 </span></p>
</li>
</ol>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">3.1、调用Object构造函数 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">内置构造器Object使用new运算符可以创建新的对象,Object构造函数为给定值创建一个对象包装器,调用构造函数时如果参数是null或undefined,将返回一个空对象,否则,将返回一个与给定值对应类型的对象。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj1=new Object(); //{} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj2=new Object({name:"foo"}); //{name:"foo"} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj3=new Object(100); //相当于new Number(100) </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">虽然这样创建obj3是Number类型的一个实例,但这种方式不推荐,增加了理解代码的复杂度。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">3.2、Object原型对象(Object.property) </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript中一切对象都是Object类型的,所有的对象都从Object.property中继承方法和属性,当然新对象可以覆盖原型对象中的成员,通过Object的原型我们可以在每个实例中访问到的属性与方法如下: </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(1)、Object.prototype.constructor属性 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">指向创建当前对象的构造函数。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(2)、Object.prototype.__proto__属性 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">指向当对象被实例化的时候,用作原型的对象。未标准化,也被标记为[]。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(3)、Object.prototype.hasOwnProperty(属性名)方法 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">用于检查某个属性是否存在当前对象中,且此属性不是从原型链继承的。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {this.name="foo";} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype={age:5}; //指定Cat的原型对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat1=new Cat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.age); //5 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //name是为cat1的自有属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.hasOwnProperty("name")); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.hasOwnProperty("age")); //false,age是从原型链中获得 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat1.hasOwnProperty("nickname")); //false,不存在的属性 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果可以看出只有存在且不是从原型链中获取的属性才返回真值。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(4)、Object.prototype.isPrototypeOf(对象)方法 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">用于测试当前对象的原型链上是否存在指定的原型,obj.isPrototypeOf(cat)则表示obj是否为cat的原型对象。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj={age:5}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype=obj; //指定Cat的原型对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat=new Cat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //obj是否为cat的原型 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(obj.isPrototypeOf(cat)); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //cat的原型链上存在Object.prototype </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.prototype.isPrototypeOf(cat)); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //Object.prototype是否为Function的原型 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.prototype.isPrototypeOf(Function)); //true </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(5)、Object.prototype.propertyIsEnumerable(属性)方法 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">用于判断指定属性是否可用for-in枚举。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj={types:}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(obj.propertyIsEnumerable("types")); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(window.propertyIsEnumerable("obj")); //true </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">因为obj没有指定为那个对象的属性,默认obj属于window对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(6)、Object.prototype.toLocaleString()方法 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">直接调用 toString()方法。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(7)、Object.prototype.toString()方法 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回对象的字符串表示。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(8)、Object.prototype.valueOf()方法 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回指定对象的原始值,通常与toString()返回的结果相同。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">3.3、Object静态成员 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">Object的静态成员直接通过"Object.成员名称"的形式调用,ES5、ES6中新增加了不少新的成员 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(1)、Object.assign() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">通过复制一个或多个对象来创建一个新的对象,如果目标对象中存在则覆盖,如果不存在则添加。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var source={a:1,b:2}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var target={b:3,c:4}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //使用source与{c:5,d:6}对象扩展target对象,返回扩展后的新对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var result=Object.assign(target,source,{c:5,d:6}); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(result); //{b: 2, c: 5, a: 1, d: 6} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(target); //{b: 2, c: 5, a: 1, d: 6} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(source); //{a: 1, b: 2} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(2)、Object.create() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">使用指定的原型对象和属性创建一个新对象。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var person = { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> name: "foo", </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> show: function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("我的名字是" + this.name); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //以person为原型创建一个新对象student </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //新对象的__proto__指向person </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var student=Object.create(person); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> student.name="bar"; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> student.show(); //我的名字是bar </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(student); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-9所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161329760-646673338.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-9 Object.create()示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果可以看了新创建的对象student的原型引用了person。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(3)、Object.defineProperty() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">给对象添加一个属性并指定该属性的配置。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(4)、Object.defineProperties() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">给对象添加多个属性并分别指定它们的配置。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(5)、Object.entries() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回一个给定对象自身可枚举属性的键值对数组,与for-in的区别是,for-in循环也枚举原型链中的属性,但entries不会。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj=Object.create({a:1,b:2}); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj.c=3; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj.d=4; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var array=Object.entries(obj); //[["c",3],["d",4]] </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> for(var i in array){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(array,array); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">最后输出的结果是:c 3,d 4。原型链中的属性a:1与b:2并未获得的原因是entries()方法不会获取原型链上的属性,而for-in是可以的。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(6)、Object.freeze() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-size: 10pt"><span style="font-family: 宋体">冻结对象,不能删除、更改、添加任何属性,<span style="color: rgba(51, 51, 51, 1); background-color: rgba(255, 255, 255, 1)">原型也不能被修改,否则在严格模式下会抛出异常,但在非严格模式下只会静默抛出异常。</span></span></span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "use strict" //使用严格模式 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj={a:1}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.freeze(obj); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj.a=2; //修改属性的值 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-10所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161330062-2006861514.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-10 Object.freeze()示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">对象obj被冻结后仍然修改其属性a的值在严格模式下抛出异常:不能访问只读属性a。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(7)、Object.getOwnPropertyDescriptor() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回对象指定的属性配置。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(8)、Object.getOwnPropertyNames() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回指定对象自身的所有属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj={a:1,b:2,c:3}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.getOwnPropertyNames(obj)); //["a", "b", "c"] </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.getOwnPropertyNames(["1",true,obj])); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //["0", "1", "2", "length"] </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(9)、Object.getOwnPropertySymbols() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回一个包含了指定对象自身所有的符号属性的数组,功能与Object.getOwnPropertyNames()类似,可以将给定对象的所有符号属性作为Symbol数组获取。Symbol是ES6中新增内容,在后面的章节中会讲到。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(10)、Object.setPrototypeOf() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">设置对象的原型([])属性,注意是对象不是函数,函数的原型可以直接通过prototype修改。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj={}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.setPrototypeOf(obj,{name:"foo"}); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(obj.name); //foo </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(11)、Object.getPrototypeOf() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回指定对象的原型对象,虽然通过__proto__也能获取对象的原型,但这并不是一个标准属性。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {} //定义构造器Cat </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var proto={name:"foo"}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype=proto; //指定构造器的原型为proto对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.getPrototypeOf(new Cat())===proto); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.getPrototypeOf(Cat)===proto); //false </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">需要注意的是从上面的代码可以看出第2次输出结果是false是因为所有函数的原型对象都指向了Function.prototype,大家要区分[]与prototype的不同。[](__proto__)是对象的属性,prototype是函数的属性。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(12)、Object.preventExtensions() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">防止对象的任何扩展,不允许添加属性,但其原型对象仍然可以添加属性,可以删除属性。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "use strict" </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj1={}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.preventExtensions(obj1); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //错误:Uncaught TypeError: Cannot add property name, object is not extensible </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj1.name="bar"; </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">只有在严格模式下才会显示抛出异常,非严格模式则是静默错误。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(13)、Object.seal() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">密封一个对象,不能添加新属性,不可删除属性,属性不可配置,属性不可删除,属性的值仍然可以修改。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "use strict" </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj1={age:18}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.seal(obj1); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> delete obj1.age; //错误:Cannot delete property 'age' of #&lt;Object&gt; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> obj1.name="foo"; //错误:Cannot add property name, object is not extensible </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(14)、Object.is(value1, value2) </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">比较两个对象是否相同,与==和===有所不同,不作类型转换,+0与-0不相等。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(15)、Object.isExtensible() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">判断对象是否可扩展,被禁止扩展、密封与冻结的对象不允许扩展。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //默认可扩展 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj1={}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.isExtensible(obj1)); //true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //被禁止扩展的对象不可扩展 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.preventExtensions(obj1); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.isExtensible(obj1)); //false </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //密封对象不可扩展 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj2 = Object.seal({}); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.isExtensible(obj2)); //false </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> // 冻结对象不可扩展 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var obj3 = Object.freeze({}); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.isExtensible(obj3)); // false </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(16)、Object.isFrozen() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">判断对象是否已经冻结,使用Object.freeze()可以冻结对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(17)、Object.isSealed() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">判断对象是否已经密封,使用Object.seal()可以密封对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(18)、Object.keys() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回一个包含所有给定对象自身可枚举属性名称的数组。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(19)、Object.values() </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">返回给定对象自身可枚举值的数组。</span></p>
<h1><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">四、封装</span></h1>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">封装(encapsulation)是面向对象编程的重要特性之一,能隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别。默认JavaScript因为没有模块、包、类与块级作用域,封装特性非常差,但通过封装可以减少代码的冗余,使代码看起来更优雅美观,所以实现封装非常必要。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">4.1、封装对象 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(1)、使用对象封装 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript中最简单的方法是通过对象将属性与方法封装在一起对外仅暴露对象名作为访问接口。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">先来看一段没有封装的代码一: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var name="小猫"; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var color="蓝色"; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function run() { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(color+"的"+name+"在跑!"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> run(); //蓝色的小猫在跑! </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">上面的代码虽然实现了简单的功能但对外暴露了3个成员(name,color与run),可以封装成一个对象,代码二如下: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var dog={ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> name:"小狗", </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> color:"绿色", </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> run:function() { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(this.color+"的"+this.name+"在跑!"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> dog.run(); //绿色的小狗在跑! </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">代码二对外只暴露了一个访问点就是dog,而且可以再添加更多的属性与方法,而代码一随着功能的增加对外暴露的成员会更多。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>(2)、使用构造器封装 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">通过对象可以封装但没有复用性,重复的脚本会引起许多问题,使用构造器封装可以解决对象封装的不能复用的缺陷。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Animal(name,color) { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> this.name=name; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> this.color=color; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Animal.prototype.run=function () { //在原型中添加run方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(this.color+"的"+this.name+"在跑!"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat=new Animal("小猫","蓝色"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var dog=new Animal("小狗","绿色"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cat.run(); //蓝色的小猫在跑! </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> dog.run(); //绿色的小狗在跑! </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">需要注意的是没有将run方法写在构造器中的原因是:函数也是对象,每次新创建对象时都要再创建函数对象,这样会降低性能,而将方法放在原型则被所有对象共享,只需创建一次即可。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">使用构造器同样达到了封装的目的,当然他与对象的封装可以应用在不同的场景,两者并不矛盾,本质上构造器只是提供了一种创建对象的方法。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">4.2、数据属性 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">数据属性包含一个数据值的位置,这个位置可以读取和写入值,直接在对象中定义的属性就是数据属性。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var dog={color:"白色"}; //数据属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //{value: "白色", writable: true, enumerable: true, configurable: true} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(Object.getOwnPropertyDescriptor(dog,"color")); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">Object.getOwnPropertyDescriptor用于获得属性的描述对象,从输出结果可以看出直接定义的属性的默认配置值。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">ES5中通过Object.defineProperty()方法可以定义属性,可以通过参数配置属性的特征,方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回该对象。语法如下: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">Object.defineProperty(<em>要定义属性的对象,属性名称,属性的特征描述对象</em>) </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">属性描述对象中的4个参数: </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>configurable:</strong>是否允许通过delete删除属性,能否修改属性的特性,是否允许把属性修改为访问器属性,默认为false。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>enumerable:</strong>是否可枚举,也就是能否通过for-in循环返回属性,默认为false。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>value:</strong>该属性对应的值,默认为 undefined。</span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>writable:</strong>是否允许修改属性的值。默认为 false。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var dog={color:"白色"}; //普通数据属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.defineProperty(dog,"name",{ //定义带描述对象的数据属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> writable:false, //只读 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> value:"小狗", //默认值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> enumerable:false, //不可枚举(遍历时不出现) </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> configurable:false //不可重新配置 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> dog.name="狗狗"; //修改属性name的值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> delete dog.name; //删除属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(dog.name); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.defineProperty(dog,"name",{ //重新配置,报错 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> writable:true </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-11所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161330337-1424925337.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-11 数据属性示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果可以看出因为不可写所以输出的值还是初始值,如果在严格格式下将直接抛出错误(Cannot assign to read only property 'name' of object '#&lt;Object&gt;');因为描述对象不允许再配置所以再配置时抛出了错误。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">4.3、访问器属性 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">访问器属性与数据属性不一样,它不包含数据值,使用getter与setter函数,getter实现读,setter实现写,访问器属性不能直接定义,需要使用Object.defineProperty()静态函数,语法格式与数据属性的一样,但描述对象有些区别,对应的4个特性如下: </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>configurable:</strong>是否允许通过delete删除属性,能否修改属性的特性,是否允许把属性修改为访问器属性,默认为false。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>enumerable:</strong>是否可枚举,也就是能否通过for-in循环返回属性,默认为false。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>get:</strong>读取属性值时调用的函数,默认是undefined。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>set:</strong>写入属性值时调用的函数,默认是undefined。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat={name:"小猫",_age:1}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //定义访问器属性age </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Object.defineProperty(cat,"age",{ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> configurable:true, //可再配置 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> enumerable:true, //可枚举 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> get:function () { //读 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return this._age; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }, </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> set:function (value) { //写 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> if(!isNaN(value)&amp;&amp;value&gt;0) { //约束写入值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> this._age = value; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }else{ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> throw {message:"年龄必须是大于0的数字!"}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat.age); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cat.age=-1; //写入非法值 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-12所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161330596-1787079734.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-12 访问器属性示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果可以看出当访问cat.age时间接的调用了数据属性_age,当写入的值不满足属性要求时抛出了异常。使用Object.defineProperties()时可以一次定义多个数据属性与访问器属性。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">4.4、使用闭包封装属性 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">访问器属性中的_age只是基于一种规则的约定,视下划线开始的成员为私有成员,实际上可以任意的修改_age的值,可见它并不是真正意见上的私有成员,另外ES5并非所有的浏览器都支持,使用闭包可以封装属性。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cat=(function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var _age=1; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> name:"小猫", </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> getAge:function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return _age; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }, </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> setAge:function (value) { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> if(!isNaN(value)&amp;&amp;value&gt;0) { //约束写入值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> _age = value; //注意这里没有this,因为访问的是外部函数的值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }else{ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> throw {message:"年龄必须是大于0的数字!"}; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> })(); //IIFE </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat.age); //直接访问 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cat.setAge(18); //写 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(cat.getAge()); //读 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cat.setAge(-1); //非法值 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-13所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161330833-1993385638.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-13 闭包封装属性示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-size: 10pt"><span style="font-family: 楷体"><strong>小贴士:</strong>关于IIFE、闭包与作用域的内容在上一章已经讲到,可以参考上一章的内容。</span></span></p>
<h1><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">五、继承</span></h1>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">继承(inherit)是面向对象编程的一个重要特性,继承能提高复用性,一般通过接口继承或实现继承,JavaScript无接口也无接口继承但可以通过原型实现继承。在ES2015/ES6中引入了class关键字,但那只是语法糖,JavaScript仍然是基于原型的继承。</span></p>
<h2>5.1、借调父构造函数实现属性继承</h2>
<p>使用函数的call方法可以动态的修改this的指向,为了初始化子类中的属性可以通过在子类构造器中借调父构造器完成属性的初始化,达到继承的目的,代码如下:</p>
<div class="cnblogs_code">
<pre>      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">父类,动物</span>
      <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Animal(name){
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name=<span style="color: rgba(0, 0, 0, 1)">name;
      }
      Animal.prototype.show</span>=<span style="color: rgba(0, 0, 255, 1)">function</span>(){<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">父类原型中的展示方法</span>
            console.log("这是一只名为:"+<span style="color: rgba(0, 0, 255, 1)">this</span>.name+"的狗"<span style="color: rgba(0, 0, 0, 1)">);
      }
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">子类,狗</span>
      <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Dog(name,color){
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">借调父类构造方法用于继承属性,初始化属性值</span>
            Animal.call(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">,name);
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.color=<span style="color: rgba(0, 0, 0, 1)">color;
      }

      </span><span style="color: rgba(0, 0, 255, 1)">var</span> dog=<span style="color: rgba(0, 0, 255, 1)">new</span> Dog("泰迪","白色"<span style="color: rgba(0, 0, 0, 1)">);
      console.log(dog.name,dog.color);
      console.log(dog.show);</span></pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2022.cnblogs.com/blog/63651/202206/63651-20220604060822880-681217993.png" alt="" width="249" height="103" loading="lazy"></p>
<p>&nbsp;从控制台输出结果可以看到属性name与color都继承成功了,但是原型中的show方法并没有被继承成功。</p>
<h2>5.2、继承父类原型中的函数</h2>
<p>每个函数都有原型属性prototype,prototype属性指向构造函数的原型对象,当调用构造器创建新对象时会在新对象中添加__proto__属性([])指向构造器的原型对象,所有的实例共享该原型,新创建的对象会中原型中获得新的成员,从而达到继承与复用的目的。</p>
<p>上面示例中的Dog的原型还是指向一个类型为Object的对象,并不能实现对父类原型中的对象继承,但是直接将子父类的原型指向父类的原型对象又会引起子类修改原型时影响父类的问题,这里的处理方法是将子类的原型指向一个父类的实例对象,间接的继承父类原型中的成员。</p>
<div class="cnblogs_code">
<pre>      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">父类,动物</span>
      <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Animal(name){
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name=<span style="color: rgba(0, 0, 0, 1)">name;
      }
      Animal.prototype.show</span>=<span style="color: rgba(0, 0, 255, 1)">function</span>(){<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">父类原型中的展示方法</span>
            console.log("这是一只名为:"+<span style="color: rgba(0, 0, 255, 1)">this</span>.name+"的狗"<span style="color: rgba(0, 0, 0, 1)">);
      }
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">子类,狗</span>
      <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Dog(name,color){
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">借调父类构造方法用于继承属性,初始化属性值</span>
            Animal.call(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">,name);
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.color=<span style="color: rgba(0, 0, 0, 1)">color;
      }
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">子类的原型指向一个新的父类实例,因为name初始化过,这里不再指定参数</span>
      Dog.prototype=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Animal();

      </span><span style="color: rgba(0, 0, 255, 1)">var</span> dog=<span style="color: rgba(0, 0, 255, 1)">new</span> Dog("泰迪","白色"<span style="color: rgba(0, 0, 0, 1)">);
      console.log(dog.name,dog.color);
      dog.show();
      console.dir(dog);
      console.log(Dog.prototype.constructor);</span></pre>
</div>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-14所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202206/63651-20220604061940866-357343438.png" alt="" width="322" height="397" loading="lazy"></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-14 使用原型实现继承示例运行结果</span></p>
<p style="text-align: center">&nbsp;</p>
<h2>5.3、修改原型对象中构造器的指向</h2>
<p>从上面的示例中可以看出子类的原型对象中的构造器指向是错误的,依然指向Animal构造器,应该修改其指向,代码如下:</p>
<div class="cnblogs_code">
<pre>      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">父类,动物</span>
      <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Animal(name){
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name=<span style="color: rgba(0, 0, 0, 1)">name;
      }
      Animal.prototype.show</span>=<span style="color: rgba(0, 0, 255, 1)">function</span>(){<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">父类原型中的展示方法</span>
            console.log("这是一只名为:"+<span style="color: rgba(0, 0, 255, 1)">this</span>.name+"的狗"<span style="color: rgba(0, 0, 0, 1)">);
      }
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">子类,狗</span>
      <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Dog(name,color){
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">借调父类构造方法用于继承属性,初始化属性值</span>
            Animal.call(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">,name);
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.color=<span style="color: rgba(0, 0, 0, 1)">color;
      }
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">子类的原型指向一个新的父类实例,因为name初始化过,这里不再指定参数</span>
      Dog.prototype=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Animal();
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改Dog子类原型的构造器指向Dog而非Animal</span>
      <strong><span style="color: rgba(255, 0, 0, 1)">Dog.prototype.constructor=Dog;

      </span></strong><span style="color: rgba(0, 0, 255, 1)">var</span> dog=<span style="color: rgba(0, 0, 255, 1)">new</span> Dog("泰迪","白色"<span style="color: rgba(0, 0, 0, 1)">);
      console.log(dog.name,dog.color);
      dog.show();
      console.dir(dog);
      console.log(Dog.prototype.constructor);</span></pre>
</div>
<p>输出结果:</p>
<p><img src="https://img2022.cnblogs.com/blog/63651/202206/63651-20220605055623110-1175697368.png" alt="" width="435" height="224" loading="lazy"></p>
<p style="text-align: center">&nbsp;</p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">5.4、原型链 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">当我们访问一个对象的成员时会首先查找对象自身,如果不存在时将查找__proto__所指向的原型对象,因为所有的对象都拥有__proto__属性,所以将一直向上查找,直到查找到Object.prototype对象的__proto__属性,它是指向null,这时就结束了,这就是原型链。原型链是JavaScript中实现继承的核心。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Animal() {this.name="动物";} //动物 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Dog() {this.color="白色";} //狗 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Dog.prototype=new Animal(); //继承动物 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Poodle() {this.weight="5kg";} //贵宾犬 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Poodle.prototype=new Dog(); //继承狗 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var poodle=new Poodle(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(poodle.name,poodle.color,poodle.weight); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(poodle instanceof Poodle); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(poodle instanceof Dog); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(poodle instanceof Animal); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(poodle instanceof Object); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">运行结果如图3-16所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161331630-265233150.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-16 原型链示例运行结果 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">对象与原型,原型与原型之间的关系如图3-17所示。 </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161331944-1344351943.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">图3-17 通过原型链实现继承 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出的结果可以看出poodle对象同时是Poodle、Dog、Animal与Object类型。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript中的继承因为没有统一的标准,所以根据需要出现了许多不同的形式,这里仅讲了最基本的继承方式,还有借用构造函数、组合继承、原型式继承、寄生式继承和寄生组合式继承、Object.create()等方式。</span></p>
<h1><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">六、多态</span></h1>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">多态(Polymorphism)是指同一个接口,使用不同的实例而执行不同操作,是面向对象重要特性,多态性一般表现为重写与重载。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">6.1、覆盖(Override) </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript没有接口,但支持重写功能,根据原型链中查找成员的规则自身成员的优先级高于原型链中成员的优先级,遵照就近原则。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Animal() {} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Animal.prototype={ //指定动物类型的原型对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> constructor:Animal, </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> eat:function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("动物在吃东西"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype=new Animal(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype.eat = function () { //覆盖原型对象中的eat方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Animal.prototype.eat.call(this); //调用父类中的eat方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("猫在吃小鱼"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> new Cat().eat(); //动物在吃东西 猫在吃小鱼 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">Cat.prototype.eat严格意义上来说并不是重写了Animal中的eat方法而是在自己的原型对象中添加了一个优先级更高的eat方法,使和call或apply可以调用父类中的方法且可以指定执行上下文为当前对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript是一种弱类型的动态语言,对象类型可以任意转换,这意味着JavaScript对象的多态性是与生俱来的,它在编译时没有类型检查的过程,既没有检查创建的对象类型,又没有检查传递的参数类型。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Cat() {} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Cat.prototype.eat = function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("猫在吃小鱼"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function Dog() {} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> Dog.prototype.eat = function () { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log("狗在吃骨头"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function animalEat(animal) { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> if(animal.eat instanceof Function){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> animal.eat(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> animalEat(new Cat()); //猫在吃小鱼 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> animalEat(new Dog()); //狗在吃骨头 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> animalEat(new Object()); //无输出 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">上面这段代码就达到了多态的目的,但因为没有接口的约束与语法检查eat这个函数在调用前作了判断。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">6.2、重载(Overload)</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">面向对象中同名方法不同参数满足不同的功能需要就是重载,重载增加了灵活性。JavaScript是弱类型语言,没有重载,但可以模拟实现。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //定义实现重载的加法方法 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> function add() { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //单个数字时加1 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> if(arguments.length==1&amp;&amp;typeof arguments==="number"){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return arguments++; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }else{ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //多个数字时累加 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var sum=0; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> for(var i=0;i&lt;arguments.length;i++){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> if(typeof arguments==="number"){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> sum+=arguments; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return sum; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(add(100)); //101 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(add(100,200)); //300 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(add(100,200,500)); //800 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">尽管JavaScript没有真正的重载,但是重载的达到的效果在JavaScript中却十分常见,比如Array的splice( )方法,本质都是对参数的个数与类型判断,来决定执行什么操作。</span></p>
<h1><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">七、JSON</span></h1>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">7.1、JSON概要 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JSON(JavaScript Object Notation,即JavaScript对象表示法)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于设备解析和生成。JSON采用完全独立于语言的文本格式,包含Java与C#在内的多数程序设计语言都支持JSON。JSON慢慢在取代笨重的XML。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JSON有两种结构:"键/值对"与"数组"。前者可以理解为对象、字典与结构等表现形式如下: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">{key:value,key:value,…} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">后者可以理解为序列或集合,表现形式如下: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript不是JSON,JSON也不是JavaScript,JavaScript中的对象表示与JSON非常类似但也有些区别: </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">1、属性名必须用双引号括起来;最后一个属性后不能有逗号。{age:18,}这样写在JavaScript中是正确的,但JSON中需要修改为:{"age":18}。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">2、JSON不支持undefined与变量。因为undefined是JavaScript中特殊存在的,变量需要运算才可以获得结果。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">3、数值不能出现前置零;小数点,后至少有一位数字。{"price":03,"size":1.}在JavaScript中是正确的,在JSON中就需要修改成{"price":3,"size":1.0}。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">4、字符串只能是Unicode编码。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">5、没有末尾分号,即最后一相大括号后面不要加分号。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">将语言中特定的对象转换成字符串或其它便于交换的格式称为序列化,反过来将字符串或特定格式转换成语言中的对象称为反序列化,作为一种数据交换格式这非常重要,这里只讲解JavaScript中的序列化与反序列化。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">7.2、序列化 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JavaScript中将对象转换成JSON字符串称为序列化JSON,通常会使用全局对象JSON,部分浏览器中并没有内置该对象,需要引入或Polyfill,JSON.stringify()可能将一个JavaScript对象或者数组转换为一个JSON字符串,语法格式如下: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><em>JSON.stringify(value[, replacer [, space]]) </em></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>value:要序列化的对象。 </strong></span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //产品对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var product = { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "id": 10001, "name": "手机", "price": 1937.5, </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> size: {width: 700, height: 1300} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //将JavaScript对象序列化成JSON字符串 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var json = JSON.stringify(product); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(json); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">输出:{"id":10001,"name":"手机","price":1937.5,"size":{"width":700,"height":1300}} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>Replacer:过滤(可选) </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">(1)、当该参数是一个函数时,被序列化的值的每个属性都会经过该函数的转换和处理; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //将JavaScript对象序列化成JSON字符串,并提升价格与替换名称中的关键字 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var json = JSON.stringify(product,function (key,value) { //过滤函数 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> switch (key) { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> case "price": //如果键的值是price </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return value*1.1; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> case "name": </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return value.replace(/手/igm,'耳'); //将手替换成耳,关键词过滤 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> default: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return value; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(json); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">输出:{"id":10001,"name":"耳机","price":2131.25,"size":{"width":700,"height":1300}} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从输出结果中可以看出name对应的值被替换了,价格被提高了10%,起到了过滤的作用,但如果对象与过滤函数较复杂,需注意性能问题。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">(2)、当该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的JSON字符串中。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //将JavaScript对象序列化成JSON字符串,只需要name与price属性 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var json = JSON.stringify(product,["name","price"]); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(json); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">输出:{"name":"手机","price":1937.5} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>space:缩进字符,美化输出效果(可选) </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">(1)、如果设置数字表示空格个数;最大为10,默认无空格。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //将JavaScript对象序列化成JSON字符串,美化输出结果 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var json = JSON.stringify(product,null,2); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(json); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">输出: </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">{ </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "id": 10001, </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "name": "手机", </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "price": 1937.5, </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "size": { </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "width": 700, </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> "height": 1300 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">(2)、如果设置参数为字符串则以字符串作为缩进字符。 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //将JavaScript对象序列化成JSON字符串,指定缩进字符 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var json = JSON.stringify(product,null,"+++"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(json); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">输出: </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">{ </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">+++"id": 10001, </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">+++"name": "手机", </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">+++"price": 1937.5, </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">+++"size": { </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">++++++"width": 700, </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">++++++"height": 1300 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">+++} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">} </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">在对象中定义toJSON函数也可以实现自定义序列化的需求,Date对象就定义了toJSON函数会将日期自动转换成ISO 8601日期字符串。各种开发语言对后台对象的序列化JSON的支持都非常完善了,当然也可以使用许多优秀的三方开源库。 </span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 14pt">7.3、反序列化 </span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">JSON反序列化是将JSON字符串解析成JavaScript对象。eval()函数因为存在安全风险已不再建议使用,JSON.parse可以完成该功能,其语法格式如下: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><em>JSON.parse(text[, reviver]) </em></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>text:要转换的JSON字符串 </strong></span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //JSON字符串 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var json = '{"id": 10001, "name": "手机", "price": 1937.5}'; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //解析json字符串为JavaScript对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var product=JSON.parse(json); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //访问对象中的成员 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(product.id+","+product.name+","+product.price); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">输出:10001,手机,1937.5 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>reviver:还原函数(可选)。 </strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">如果reviver返回 undefined,则当前属性会从所属对象中删除,如果返回了其他值,则返回的值会成为当前属性新的属性值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //JSON字符串 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var json = '{"id": 10001, "name": "手机", "price": 1000}'; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //解析json字符串为JavaScript对象 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var product=JSON.parse(json,function (key,value) { </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> if(key==="id"){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return undefined; //忽视id号 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> else if(key==="price"){ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return value+350; //修改价格值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> } </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> return value; //其它不变 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> }); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //输出:{"name":"手机","price":1350} </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(product); </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">从上面的输出结果可以看出id属性被过滤掉了,价格(price)值被修改,名称(name)没有影响。解析时要注意日期格式的问题,从服务端返回的日期可能是一个unix时间戳,可以在还原函数中转换。</span></p>
<h1><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 22pt">八、上机部分</span></h1>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">8.1、上机任务一(30分钟内完成)</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 12pt">上机目的 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">1、掌握创建对象的方法。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">2、掌握对象的访问操作。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">上机要求 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">1、使用3种以上不同的方式创建一个学生对象,属性与方法定义如表3-1所示,其中家庭地址是一个子对象可以分解为(省、市、县/区),print方法用于向控制台输出学生的基本属性。 </span></p>
<div style="text-align: center">
<table style="border-collapse: collapse" border="0">
<tbody valign="top">
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>序号</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>类别</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>中文名称</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>英文名称</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>类型</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>备注</strong></span></p>
</td>
</tr>
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">1</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" rowspan="6" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">属性</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">学号</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">no</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">Number</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">100001-999999</span></p>
</td>
</tr>
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">2</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">姓名</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">name</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">String</span></p>
</td>
</tr>
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">3</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">生日</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">birthday</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">Date</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">出生年月日</span></p>
</td>
</tr>
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">4</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">是否在读</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">inSchool</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">Boolean</span></p>
</td>
</tr>
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">5</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">爱好</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">hobby</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">Array</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">["阅读","电影","足球"]</span></p>
</td>
</tr>
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">6</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">家庭地址</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">family address</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">Object</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">{省市县},键必须带空格</span></p>
</td>
</tr>
<tr style="height: 28px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">7</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">方法</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">打印</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">print</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">Function</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">显示所有属性</span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">表3-1 学生对象的属性与方法 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">2、对创建的对象实现取值、修改、删除、迭代与方法调用操作。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">推荐实现步骤 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤1:</strong>先用对象字面量创建创建对象、访问对象,再使用其它方式创建对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤2:</strong>反复测试运行效果,优化代码,关键位置书写注释,必要位置进行异常处理。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">8.2、上机任务二(50分钟内完成)</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 12pt">上机目的 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">1、掌握"数据属性"与"访问器属性"的定义与封装。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">2、理解原型的作用。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">2、掌握JSON的序列化与反序列化。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">上机要求 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">1、升级上机任务一,请定义一个Student构造器,指定Student原型对象,要求原型中包含如下属性与方法,具体要求如表3-2所示(表3-2中未注明的内容默认与表3-1相同)。 </span></p>
<div style="text-align: center">
<table style="border-collapse: collapse" border="0">
<tbody valign="top">
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>序号</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>类别</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>中文名称</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>可配置</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>可枚举</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>默认值</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>是否可写</strong></span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: 0.5pt solid; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt"><strong>约束</strong></span></p>
</td>
</tr>
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">1</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" rowspan="6" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">属性</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">学号</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">false</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">101</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">false</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">101-999间的数字</span></p>
</td>
</tr>
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">2</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">姓名</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">匿名</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">2-4位中文</span></p>
</td>
</tr>
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">3</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">生日</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">false</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">1970-01-01</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">不能超过当天</span></p>
</td>
</tr>
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">4</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">是否在读</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
</tr>
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">5</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">爱好</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">[]</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">最多5个</span></p>
</td>
</tr>
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">6</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">家庭地址</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">{}</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">true</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">省市县不允许为空</span></p>
</td>
</tr>
<tr style="height: 31px">
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: 0.5pt solid; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">7</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">方法</span></p>
</td>
<td style="padding-left: 9px; padding-right: 9px; border-top: none; border-left: none; border-bottom: 0.5pt solid; border-right: 0.5pt solid" valign="middle">
<p style="text-align: justify"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">打印</span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">表3-2 原型中的属性要求 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">2、调用构造函数实例化一个学生对象,设置每一个属性值,测试属性配置是否正确。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">3、对创建的对象实现取值、修改、删除、迭代与方法调用操作。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">4、请同时使用"数据属性"与"访问器属性"定义学生的原型对象,方法不变。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">5、将创建的对象序列化成JSON字符串,要求将爱好合并成一个字符串,用逗号分隔开;生日显示为:yyyy-MM-dd格式;使用3个空格缩进;输出结果到控制台。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">6、再将序列化后的JSON字符串反序列化成JavaScript对象,增加print方法,调用方法显示所有的属性值。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">推荐实现步骤 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤1:</strong>定义Student构造器,定义一个原型对象,在原型对象中定义数据属性,根据表格的要求设置每个属性的描述信息。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤2:</strong>调用构造函数创建对象,测试对象的使用。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1)"><span style="font-family: 宋体; font-size: 10pt"><strong>步骤3:</strong>重新指定原型对象,使用"</span><span style="font-family: 等线; font-size: 10pt">访问器属性</span><span style="font-family: 宋体; font-size: 10pt">"设置每个属性的描述信息,重复步骤2。 </span></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤4:</strong>完成序列化与反序列化功能。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤5:</strong>反复测试运行效果,优化代码,关键位置书写注释,必要位置进行异常处理。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">8.3、上机任务三(20分钟内完成)</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 12pt">上机目的 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">1、理解prototype对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">2、掌握扩展内置对象的方法。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">3、了解JavaScript单元测试与测试框架。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">上机要求 </span></p>
<ol style="margin-left: 39pt">
<li><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">编写3个扩展方法,增强Date与Number内置对象,补充下面的代码。 </span></li>
<li>
<div><span style="color: rgba(0, 0, 0, 1); font-size: 10pt"><span style="font-family: 等线">weekday方法获得日期对象的星期,unixTimestamp</span><span style="font-family: 宋体">将日期转换成Unix时间戳,toDate方法将Unix时间戳(Unix timestamp)转换成日期。</span></span></div>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> /**1、扩展Date对象,添加weekday方法*/ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> /**2、扩展Date对象,添加unixTimestamp方法*/ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> /**3、扩展Number对象,添加toDate方法*/ </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var date=new Date(2031,11,29,12,59,35);//创建一个日期对象,指定年月日时分秒 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //获得date的星期值 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(date.weekday()); //输出:星期一 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //将日期转换成Unix时间戳(Unix timestamp) </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(date.unixTimestamp()); //输出:1956286775 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //将Unix时间戳(Unix timestamp)转换成日期 </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> console.log(new Number(1956286775).toDate().toLocaleString()); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 12pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> //输出:2031/12/29 下午12:59:35 </span></p>
</li>
<li><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">使用Mocha、Jest、Chai等测试框架完成单元测试。(选作) </span></li>
</ol>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 楷体; font-size: 10pt"><strong>提示:</strong>Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。Unix时间戳不仅被使用在Unix系统、类Unix系统中,也在许多其他操作系统中被广泛采用。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 楷体; font-size: 10pt">Date类型的getTime()方法可返回距1970年1月1日之间的毫秒数。new Date(毫秒)构造函数是支持使用毫秒创建日期对象。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">推荐实现步骤 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤1:</strong>创建脚本文件,依次扩展3个方法并测试是否达到预期效果。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤2:</strong>反复测试运行效果,优化代码,关键位置书写注释,必要位置进行异常处理。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">8.4、上机任务四(50分钟内完成)</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 12pt">上机目的 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">1、掌握基本的继承方法。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">2、理解多态。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">3、了解Canvas绘画技术。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">上机要求 </span></p>
<ol style="margin-left: 39pt">
<li><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">如图3-18所示创建3个构造函数,定义好属性与方法,draw方法向控制台输出当前形状的位置,area方法计算形状的面积。构造方法要求可以初始化所有参数。 </span></li>
</ol>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161332327-1801815894.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">图3-18 继承关系 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">2、实现形状间的继承关系,如图3-18所示。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">3、分别创建不同类型的测试对象,定义对象时传入参数,调用对象中的方法。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">4、重写draw方法,通过Canvas实现绘图功能,参考代码如下所示: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">&lt;canvas id="canvas1" width="300" height="150"&gt;&lt;/canvas&gt; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">&lt;script&gt; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var c=document.getElementById("canvas1"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> var cxt=c.getContext("2d"); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cxt.fillStyle="#FF0000"; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cxt.fillRect(100,100,100,50); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cxt.beginPath(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cxt.arc(50,50,40,0,Math.PI*2,true); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cxt.closePath(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cxt.fillStyle="#0000FF"; </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"> cxt.fill(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">&lt;/script&gt; </span></p>
<p style="text-align: center"><img src="https://img2022.cnblogs.com/blog/63651/202205/63651-20220519161332560-1522159111.png" alt=""></p>
<p style="text-align: center"><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">图3-19 Canvas绘图参考示例 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">5、定义一个drawHandler方法,接受不同的形状实例,调用绘图方法,在页面上绘出不同的图形,请使用多态的方式。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 等线; font-size: 10pt">6、参照图3-4与图3-15画出对象、函数、原型、Function与Object间的关系图。(选作) </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑">推荐实现步骤 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤1:</strong>创建页面,按要求定义好三个构造方法,并实现其继承关系,测试效果。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1)"><span style="font-family: 宋体; font-size: 10pt"><strong>步骤2:</strong>学会HTML5中使用</span><span style="font-family: 等线; font-size: 10pt">Canvas绘画的基本技巧后,重写draw方法</span><span style="font-family: 宋体; font-size: 10pt">。 </span></span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt"><strong>步骤3:</strong>反复测试运行效果,优化代码,关键位置书写注释,必要位置进行异常处理。</span></p>
<h2><span style="color: rgba(0, 0, 0, 1); font-family: 微软雅黑; font-size: 16pt">8.5、代码题</span></h2>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">1、定义一个对象实现深拷贝,即克隆一个完全独立的对象,有多种方式可以实现,试比较他们之间的区别。 </span></p>
<p><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">2、扩展Date对象,实现日期格式化功能,效果如下所示: </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">var date = new Date(); </span></p>
<p style="background: rgba(240, 240, 240, 1); margin-left: 51pt"><span style="color: rgba(0, 0, 0, 1); font-family: 宋体; font-size: 10pt">date.formate("yyyy-MM-dd hh:mm:ss") //输出:2032-01-15 23:59:59 </span></p>
<h1>九、源代码</h1>
https://gitee.com/zhangguo5/JS_ES6Demos.git
<h1>十、教学视频</h1>
https://www.bilibili.com/video/BV1bY411u7ky?share_source=copy_web<br><br>
来源:https://www.cnblogs.com/best/p/16288959.html
頁: [1]
查看完整版本: JS与ES6高级编程学习笔记(三)——JavaScript面向对象编程