1.bom:BOM的接口由宿主环境(host environment)定义,用于控制文档之外的部分,以便语言和环境进行交互。这里所说的宿主环境,通常是指浏览器。
2.常见笔试题:JavaScript有哪些优势和劣势?
答案:JavaScript主要有如下几方面的优势:
(1)JavaScript可在客户端替服务器分担一些工作(例如数据验证、数学计算等),从而减少和服务器的交互次数,降低服务器压力。
(2)JavaScript比较容易上手,日常开发涉及的大部分语法都比较简单。
(3)用户能快速得到页面上的反馈,除了一些必须与服务器通信的操作,例如提交数据、验证昵称重复等,这些操作会有无法避免的网络延迟,而其他在客户端运行的大部分操作,都能得到即时反馈。
(4)跨平台,JavaScript不会依赖操作系统(例如Windows、iOS等),只要有浏览器,就能正常执行。
(5)丰富界面、增强交互,JavaScript可以控制文档中的任何元素,定制元素的内容、样式或行为,也可以替代CSS实现复杂而多样的动画或特效(例如点击元素改变背景色)。
当然JavaScript也有缺点,如下所列:
(1)兼容性低,各个浏览器对JavaScript的支持程度不同,同一套脚本在不同浏览器中的执行结果会不同,有的完美执行,有的可能会提示错误。
(2)安全性低,由于JavaScript在客户端运行,用户不但可以查看JavaScript源代码,还能嵌入恶意代码、替换或禁用脚本。
(3)中断运行,JavaScript是一种解释语言,只要有一条出错,就会直接停止运行。
(4)权限限制,JavaScript不能直接与操作系统交互,中间隔了个浏览器,浏览器只赋予了JavaScript很少的权限,例如写文件都是不允许的。
3.Null的返回值是object
4.一种特殊的跳转语句:除了return,break,continue,还有一种label语句,
5.什么叫字面量?
答案:字面量(literal)就是常量,值是固定的,在程序中可以直接使用的数据值,在JavaScript中,可以使用各种字面量,例如数字字面量、字符串字面量、对象字面量等,下面列出的都是字面量:整数浮点数,字符串,数组,对象,正则表达式,布尔值等。
分号会在什么时候自动补全?自动补全有什么弊端?
答案:一条语句会以分号(;)结束,语句之间也会用分号来隔开。分号可以增强脚本的可读性和整洁性,但JavaScript并不强制使用分号。如果省略了分号并且无法正确解析代码,那么JavaScript解释器就会根据自己的判断在某个位置插入分号。让JavaScript自动补全分号很有可能改变代码的行为,例如一条以(、[、/、+、-这些字符开头的语句,有可能会与前一条语句合并在一起,作为一个整体被解析,如下列代码所示。平时养成良好的编程风格,在句末补全分号,能够避免很多不必要的错误。
什么是严格模式?严格模式有哪些限制?
答案:ECMAScript 5引入了严格模式(strict mode)的概念。严格模式对JavaScript的语法和行为都做了一些更改,消除了语言中一些不合理、不确定、不安全之处;提供高效严谨的差错机制,保证代码安全运行;禁用在未来版本中可能会使用的语法,为新版本做好铺垫。在脚本文件第一行或函数内第一行引入“use strict”这条指令(代码如下所示),就能触发严格模式,这是一条没有副作用的指令,老版的浏览器会将其作为一行字符串直接忽略。
严格模式常见的限制有以下几条:
(1)所有的变量要先声明,无法再意外创建全局变量。
(2)函数中this对象的默认值是undefined,而不是全局对象(window)。(3)试图使用delete运算符删除不可删除的属性会抛出异常。
(4)函数声明中定义两个或多个同名参数将产生一个语法错误,例如sum(x,x){}。
(5)禁止使用以0为前缀的八进制数字(例如010),以0x为前缀还是支持的。(6)禁止使用with语句。
(7)不能将eval和arguments用作变量、函数或参数的名称。
undefined和null有哪些异同?
答案:先来了解一下undefined和null的相同部分,如下所列:
(1)都有空缺的意思。
(2)不包含方法和属性。
(3)都是假值。
(4)都只有一个值。
再来了解一下两者的不同部分,如下所列:
(1)含义不同,undefined表示一个未定义的值,null表示一个空的对象。
(2)类型不同,将typeof运算符应用于undefined,得到“undefined”;
而应用于null,得到的却是“object”。
(3)数字转换结果不同,将undefined和null用全局函数Number()转换为数字,得到的结果分别为NaN和0。
(4)在非严格模式中的表现不同,undefined可以是一个标识符,能被当作变量来使用和赋值,而null不行。
6.isFinite()能够判断一个数字是否有限;
isFinite(null); //true
isFinite(0); //true
isFinite(NaN); //false
isFinite(Infinity); //false
isNaN()能够判断一个数字是不是NaN;
NaN==NaN返回的是false
7.math的常量和方法
8.字符串的不可变:字符串一经创建就不可改变,使用它的成员方法例如toLocaleLowerCase()等也不会改变其原始值,而是返回一个新的值,它们两者是不相等的。
字符串虽然看上去长得与数组很像,但是它只能读取数据,而不能改变数据。
9.string的属性与方法
10.在下面的代码中,每个表达式计算后得到的结果是什么?
3.toFixed(2)
3…toFixed(2)
3.1…toFixed(2)
3 .toFixed(2)
3.1465.toFixed(2)
答案:toFixed()是内置对象Number中的一个方法,用于格式化一个浮点数,返回数字的字符串形式,它的参数用于指定小数部分的显示位数,并且会对指定的最后一位进行四舍五入,如果小数部分的实际位数达不到指定的位数,就用0来补齐。点号(.)既可以作为浮点数中的小数点,也可以作为成员访问运算符,但会被优先识别为小数点。
(1)“3.toFixed(2)”是无效语法,因为点号被识别为浮点数“3.”的一部分,失去了成员访问运算符,就无法调用toFixed()方法。
(2)“3…toFixed(2)”的计算结果为“3.00”,增加了一个点号,解决了第一个表达式中的问题,第二个点号作为成员访问运算符,调用toFixed()方法。
(3)“3.1…toFixed(2)”也是无效语法,有一个多余的点号。
(4)“3 .toFixed(2)”,看上去与第一个表达式类似,但加了一个空格变成了有效语法,计算结果为“3.00”。
(5)“3.1465.toFixed(2)”的计算结果为“3.15”。
如何将字符串"pwstrick"反转为"kcirtswp"?
答案:先将字符串变成一个数组,再用数组的成员方法reverse()颠倒数组中元素的排列顺序,最后用join()方法连接所有元素,组成一个新的字符串。
“pwstrick”.split("").reverse().join("");
截取字符串的3个方法:slice()、substring()和substr()有哪些区别?
答案:这3个方法都有两个参数,第一个都是必选项,第二个都是可选项。下面先列举参数之间的区别,如表所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VVR2Cm4F-1614533829047)(C:\Users\ZQT\AppData\Roaming\Typora\typora-user-images\image-20201221164011925.png)]
slice()和substring()的参数含义相同,两者表面比较类似,但在实际使用中还是有较多区别的,如表所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Arbv0GlF-1614533829053)(C:\Users\ZQT\AppData\Roaming\Typora\typora-user-images\image-20201221164051974.png)]
针对substr()的两个参数,分5种情况进行说明,如表所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z5X16ufa-1614533829057)(C:\Users\ZQT\AppData\Roaming\Typora\typora-user-images\image-20201221164138134.png)]
11.强制类型转换
有3个转型函数(Number()、parseInt()和parseFloat())和1个运算符(一元加号)可以将非数字类型的值转为数字。
Number():如果是纯数字,直接转化成数字;如果字符中有非数字或者undefined,直接转化成NaN;如果字符串是一个空串或者是一个全是空格的字符或者是null,则转化成0;布尔转数字,true转成1,false转成0;
parseInt():parseInt()能将字符串解析为指定基数的整数。(小数只剩整数部分)
parseFloat():将字符串转化成浮点数;(这两种专门用来对付字符串)
a="123.786px";
a=parseInt(a);
console.log(a); //"123",只取整数,不像Number方法啥都识别不出来
a=parseFloat(a);
console.log(a); //"123.786",可以识别到小数部分
如果对非String使用parseInt()和parseFloat(),他会先将其转换成String再操作。
a=true;
a=parseInt(a);
console.log(typeof a); //"number"
console.log(a): //"NaN"
在js中用0x表示16进制,用0开头表示8进制;一般不用二进制,有的浏览器识别不出来;
070有的浏览器会识别成八进制,有的会识别成八进制;
a="070";
a=parseInt(a,8); //56
a=parseInt(a,10); //70,用来区分八进制和十进制
12.按非位取反~
~null/undefined/“pw”/{} 结果都是-1
-1.25 //-2 浮点数的小数部分会被截除
indexOf():搜索指定的子串,出现的话返回第一次出现的位置,不出现的话返回-1;
13.转化成字符串
toString()和String()可以将非字符串类型的值转为字符串。
1.只有数字的toString()方法才能接受一个可选的参数(radix),用于指定计算时的基数,例如:(10)toString(16); //“a”
null,undefined这两个值没有toString,如果调用他们的方法会报错。
2.String():String()可以将任何类型的值转换为字符串,包括null和undefined,但不能指定数字计算时的基数。
String(null); //“null”
String(undefined); //“undefined”
String({}); //"[object Object]"
3.“”+true; //“true”
14.转化成布尔值
①Boolean();只有7个值能通过Boolean()方法转换成false,它们是undefined、null、0、-0、NaN、""和false,这类值被称为假值;其余的值(包括{}、[]等)都能被转换成true,这些值被称为真值。
Boolean(null); //false
15.赋值运算符
相等和全等=
“”允许在比较中进行类型转换,而“=”禁止类型转换
a+=5 等价于a=a+5;
16.运算符
①通过运算符可以对一个或多个值进行计算,例如typeof();
②运算符不会对原变量造成影响,除非再赋值一个变量;
③在对非number的值进行计算的时候,会将它转换成number在再计算:
④任何值和NaN做运算都是NaN;
result=2+NaN; //NaN
⑤如果对两个字符串相加会造成拼串;
⑥任何值和字符串做加法运算,都会转换成字符串,然后再和字符串做拼串的操作;”除了这种情况,都转化成number计算,也就是③“
任何值做-*/运算时都会自动转换成number;
17.一元运算符(只需要一个操作数)
+正号
正号不会对数字产生任何影响
-负号
对于非number,他会先变成number再计算;
18.自增和自减
i++是自增之前的值,++i是自增之后的值;
19.与或计算
布尔值就正常计算
非布尔值先转换成布尔值再进行计算
①result=2&&1; //1 如果两个都为true,则返回后面的
② result=NaN&&0; //NaN 如果两个值都为false,则返回前面的值
或运算则相反,自己想
20.关系运算符
非数值计算的时候先转化成数值然后在进行计算;如果都是字符串,不会转化成数字,而是直接比较;
console.log(“11”<“12”); //true;
21.常见笔试题:
1.以下代码最终在控制台输出的结果为多少?
var a={};
b={name:"ping"};
c={name:"wen"};
a[b]=10;
a[c]=20;
console.log(a[b]);
答案:在控制台输出的结果为20。b和c都是对象,当作为a对象的属性名时,会被类型转换为字符串,两个对象转换后的值都为“[objectObject]”,两句赋值语句于下面的代码。
a["[object Object]"]=10;
b["[object Object]"]=20;
2.以下每个表达式输出是多少?
!{}[true]; //
22.全局变量
当一个变量在声明时,没有显式的var关键字,就默认是一个全局变量。
同字符串一样,数字和布尔值也能执行隐式封装,分别使用构造函数Number()和Boolean()创建对象。存取字符串、数字或布尔值时创建的对象称为包装对象,null和undefined没有对应的包装对象,如果访问它们的属性,那么会抛出一个不能读取属性的异常(即错误)
23.处理URI的全局函数
JavaScript有3对全局函数,专门用于URL编码和解码,3个编码函数都不会对英文字母和数字进行编码操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ef9iVwsf-1614533829064)(C:\Users\ZQT\AppData\Roaming\Typora\typora-user-images\image-20201222211516368.png)]
24.常见笔试题
1.请说明JavaScript中的原生对象(native objects)和宿主对象(hostobjects)。
答案:原生对象是由ECMAScript规范定义的对象,所有内置对象都是原生对象,例如Array(数组)、Date(日期和时间)和RegExp(正则表达式)等。宿主对象是由宿主环境(如浏览器)定义的对象,用于完善ECMAScript的执行环境,例如Document、Location和Navigator等
2.全局函数eval()有什么作用?
答案:eval()可以执行一段字符串中的脚本,它只有一个参数,如果传入的参数是非字符串类型的值,那么就直接返回该值。如果传入字符串字面量,那么将被作为JavaScript代码进行编译。当编译失败时,抛出一个语法错误;当编译成功时,则开始执行这段代码,最后返回一个表达式或语句的值。eval()的具体用法如下所示。
eval(1); //1
var str="var total=100;console.log(total)";
eval(str); //100
在eval()中创建的变量或函数具有当前执行时所处的作用域,并且声明不能被提升,因此如果在调用eval()之前使用函数中创建的变量,将会抛出未定义的异常,如下所示。
function sum(){
var digit=1;
console.log(total); //抛出未定义的异常
eval("var total=100;"); //定义变量
console.log(total); //total和digit的作用域相同
}
在严格模式中,eval()不能改变作用域,因此也就不能定义新的变量或函数,如下所示。
function sum(){
"use strict";
eval("var total=100;"); //定义变量
console.log(total); //抛出未定义的异常
}
eval()编译代码字符串的能力非常强大,同时也非常危险。如果传入的是恶意代码,那将会威胁站点的安全,造成不可估量的损失。
25.对象
与基本类型不同,对象是可变的,当把一个对象赋给变量时,获得的不是对象副本,而是引用该对象的指针,如下所示。
var obj1={name:"strick"},obj2=obj1;
obj2.name="pingwen";
console.log(obj1); //{name:"pingwen"}
console.log(obj2); //{name:"pingwen"}
//变量obj2引用了obj1的指针,改变了obj1里name的值,所以输出的结果都是相同的。
26.创建
1.构造函数:使用运算符new(可省略)和Object的构造函数(constructor)能创建一个新的Object实例。
Object(); //空对象
new Object(); //空对象
new Object(null); //空对象
new Object(undefined); //空对象
Object(1); //Number对象
new Object(1); //Number对象
2.字面量:对象字面量是创建对象的一种简写形式,只需将属性或方法放入一对花括号中,再用逗号隔开,就完成了对象的创建。使用对象字面量创建对象时,不会调用Object的构造函数,并且每次都会创建一个新的对象。在下面的代码中,创建了两个简单的对象字面量。
var obj1={}; //空对象,不需要使用Object的构造函数创建
var obj2={name:"strick",age:28}; //多个属性
27.原型prototype
①我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,这个对象就是我们所谓的原型对象;
②如果函数作为普通函数调用prototype没有任何作用,但是当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性指向该构造函数的原型对象,我们可以通过_____proto_来访问该属性。
③原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。
④当我们访问对象的一个属性或方法时,他会先在对象自身中寻找,如果找到则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。
function MyClass(){
}
//向MyClass的原型中添加属性a
MyClass.prototype.a=123;
//向MyClass的原型中添加一个方法
MyClass.prototype.sayHello = function(){
alert("Hello!");
};
var mc=new MyClass();
var mc2=new MyClass();
mc.sayHello(); //弹出Hello!
console.log(mc2._proto_==MyCLass.prototype); //true
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dz0HphOv-1614533829067)(C:\Users\ZQT\AppData\Roaming\Typora\typora-user-images\image-20201223000647715.png)]
⑤使用in检查对象中是否含有某个属性或方法时,如果对象中没有但是原型中有也会返回true;但是可以使用对象的hasOwnProperty()来检查对象中是否含有自身属性,只有对象自身中含有自身属性时才会返回true。
⑥原型对象也是对象,所以他也有原型,当我们使用一个对象的属性和方法时,现在自身中寻找,如果自身有,则直接使用;如果自身没有,则去原型中寻找,有则使用;如果原型没有,则去原型的原型里寻找;以此类推 ,知道找到Object对象的原型;
Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined;
这些就被称为原型链。
28.补充toString()
当我们直接在页面中打印一个对象时,事实上是输出对象的toString()方法的返回值;
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
//创建一个Person实例
var per=new Person("孙悟空","18","男");
console.log(per); //"[object Object]"
//当我们直接在页面中打印一个对象时,事实上是输出对象的toString()方法的返回值;
console.log(per.toString); //跟上面那个是一样的
var result=per.toString();
console.log("result="+result); //result=[object Object]
console.log(per.hasOwnProperty("toString")); //false,说明不在它自己的对象之中,要去原型之中去寻找
console.log(pre.__proto__.__proto__.hasOwnProperty("toString"));
//如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法来代替原型中的那个方法;
per.toString()=function(){
retPPPPPPPPPPurn "我是一个快乐的小person";
//return "Person[name="+this.name+",age="+this.age+",gender="+this.gender];
}
console.log("result="+result); //"result=我是一个快乐的小person"
29.垃圾回收
就像人生活的时间长了会产生垃圾一样,程序运行过程中也会出现垃圾,这些垃圾积攒过多后,会导致程序运行的速度过慢;
当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,所以这种垃圾必须进行清理。
在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们也不需要也不能进行垃圾回收的操作。
30.内建对象和宿主对象(还有一个自定义对象)
数组(Array)
数组也是一个对象,它和普通的对象功能类似,也是用来存储一些值的;不同的是普通对象是使用字符串作为属性名的,而数组是使用数字来作为索引操作元素。
索引
从0开始的整数就是索引;
var arr = new Array();
var arr = []; //创建数组
使用typeof()来检查一个数组时,会返回object;
数组的四种常用方法:
var result = arr.push("tang"); //向数组末尾添加一个元素,返回的是数组长度
console.log(result); //7,这是数组的长度
var result = arr.pop(); //删最后一个元素,返回删掉的元素
console.log(result); //返回的是刚刚删掉的元素
arr.unshift("tang"); //向数组最前面添加一个元素,返回数组长度
arr.shift(); //删除数组的第一个元素,并将删掉的元素返回
数组的遍历:
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
一个简单的小例子,将年龄大于等于18的全都提取到另一个数组里。
function Person(name,age){
this.name=name;
this.age=age;
}
var per = new Person("孙悟空",18)
var per2 = new Person("...")
var per3 = new Person("...")
var per4 = new Person("...")
var per5 = new Person("...")
var PerArr = [per,per2,per3,per4,per5];
function getAdult(arr){
var newArr = [];
//遍历arr,获取arr里的person对象
for(var i=0;i<arr.length;i++){
var p = arr[i];
//判断Person对象的age是否大于等于18;
if(p.age >= 18){
newArr.push(p);
}
}
}
31.forEach();
var arr = ["sun","zhu","sha","tang","bai"];
arr.forEach(function(value,index,obj)){
console.log(value);
};
//forEach()方法需要调用一个函数作为参数,像这种函数,由我们创建但不是由我们调用的,我们称为回调函数 ;数组中有几个元素,函数就会执行几次,每次执行时,浏览器会将遍历到的元素以实参的形式传递进来,我们可以定义到形参,来读取这些内容。
//浏览器会在回调函数中传第三个参数,第一个参数就是当时正在遍历的元素;第二个参数就是当前正在遍历元素的索引;第三个参数就是当前正在遍历的数组。
32.slice()和splice()
var arr = ["sun","zhu","sha","tang","bai"];
var result = arr.slice(1,3); //result=["zhu","sha","tang"]
//使用slice不会影响原数组
var result = arr.splice(0,2,"niu");
console.log(arr); //["niu","sha","tang","bai"]
console.log(result); //["sun","zhu"]
//第一个是开始位置的索引,第二个是删除的数量,第三个可以插入开始位置索引的前面
去重(不新建一个数组的方法)
var arr = [1,2,3,2,2,1,3,4,2,5];
//获取数组中的每一个元素
for(var i=0;i<arr.length;i++){
//获取当前元素之后的所有元素
for(var j=i+1;j<arr.length;j++){
if(arr[i]=arr[j]){
//如果相等则证明出现了重复的元素,则删除j对应的元素
arr.splice(j,1);
//删除了j所在的元素之后,后面的元素会自动补位,此时不会再比较这个元素,而是会比较下一个,所以需要j自减
j--;
}
}
}
数组的其他方法:
var arr = ["sun","zhu","sha"];
var arr2 = ["bai","yu","zhi"];
var result = arr.concat(arr2); //"sun,zhu,sha,bai,yu,zhi",concat可以连接两个数组,不会改变原数组;
var result = arr.concat(arr2,arr3,"niu","zhang");
var result = arr.join(); //"sun,zhu,sha";看属性知道join使数组转化成字符串
var result = arr.reverse(); //"sha,zhu,sun",该方法用来反转数组,且会直接对原数组产生影响
var arr3 = ["b","d","e","a","c"];
arr3.sort();
console.log(arr3); //"a,b,c,d,e";sort方法可以对数组中的元素进行排序;即使是对纯数字的数组排序,也会按照Unicode编码来排序,所以对数字进行排序时,可能会得到错误的结果,比如11<2;
//我们可以自己来指定排序的规则,在sort()中添加一个回调函数
//浏览器会根据回调函数的返回值来决定元素的顺序,如果返回一个大于0的值,则元素会交换位置;如果返回一个小于0的值,则元素位置不变;如果返回一个零,则认为元素相等,也不交换位置;
var arr = [1,3,6,4,5,8,2];
arr.sort(function(a,b){
/*if(a>b){
return -1;
}else if(a<b){
return 1;
}else{
return 0;
}*/
//升序排列
return a-b;
//降序排列
return b-a; //可以根据这两句话决定是升序还是降序排列
}
)
33.函数对象的方法:call()和apply(),需要函数对象来调用;
function fun(){
alert("我是fun函数!");
}
//调用call()和apply()都会调用函数执行;
fun.apply();
fun.call();
fun(); //三个函数调用结果是一样的
var obj = {};
fun.call(obj); //在调用call和apply时可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this,比如说alert(this),本来执行出来是[object Window],但是fun.call(obj)之后,执行出来就是[object Object]
function fun(a,b){
console.log(a);
console.log(b);
}
fun.call(obj,2,3); //call()方法可以将实参在对象之后依次传递
fun.apply(obj,[2,3]); //apply()方法需要将实参封装到一个数组中统一传递
/*this的情况
1.以函数的形式调用时,this永远都是window;
2.以方法的形式调用时,this是调用方法的对象;
3.以构造函数的形式调用时,this是新创建的那个对象;
4.使用call和apply调用时,this是指定的那个对象。
34.arguments
35.Date对象
36.math
//Math不是一个构造函数,它属于一个工具类不用创建对象,它里面封装了数学运算相关的属性和方法;
//属性
console.log(math.PI); //打印出pi值
//方法
console.log(Math.abs(-1));
console.log(Math.ceil(1.4)); //2,Math.ceil()可以向上取整
console.log(Math.floor(1.99)); //1,向下取整
console.log(Math.round(1.4)); //四舍五入
Math.random();
Math.pow(x,y); //返回x的y次幂
37.字符串的方法
str.length();
str[0];
str.charAt(0); //返回字符串中指定位置的字符,不会改变原字符串
str.charCodeAt(0); //返回字符串指定位置的Unicode编码
string.fromCharCode(72); //根据字符编码获取字符,是构造函数调用的方法,不是对象