目录
一、原始值的包装类型
为了方便操作原始值,JS提供了三种特殊的引用类型:Boolean,String,Number
1.什么是原始值的包装类型?
上面说的这三种类型仍然是原始数据类型,只是他们具有引用类型一样的特点,同时也具有各自原始类型对应的特殊行为
let str=new String('abc');
//定义了一个字符串包装类型str,str是一个对象,它具有引用类型一样的特点,同时也具有字符串
//的特殊行为
let str2='abc';
//定义了一个字符串str2,str2是一个原始值,但是可以调用方法
原始值本身不是对象,因此逻辑上不应该有方法,而实际上原始值的包装类型可以调用方法
话不多说上实例:
let str1='hello world';
let str2=str1.toUpperCase();//将str1字符串转换为大写赋值给str2
console.log(str2);//HELLO WORLD
解析:我们知道,原始值本身不是对象,因此逻辑上不应该有方法,当第二行访问 s1 时,是以读模式
访问的,也就是要从内存中读取变量保存的值。在以读模式访问字符串值的任何时候,后台都会执行以
下 3 步:1.创建一个 String 类型的实例;
2.调用实例上的特定方法;
3.销毁实例。
2. 原始值的包装类型与引用类型有什么区别?
引用类型与原始值包装类型的主要区别在于对象的生命周期【这里讨论的是系统自动创建的原始值的引用类型与对象的区别】
let s1 = "some text";
s1.color = "red";
console.log(s1.color); // undefined
// 1、第二行代码尝试给字符串 s1 添加了一个 color 属性
// 2、可是,第三行代码访问 color 属性时,它却不见了
// 3、原因就是第二行代码运行时会临时创建一个 String 对象,
// 而当第三行代码执行时,这个对象已经被销毁了
// 4、实际上,第三行代码在这里创建了自己的 String 对象,但这个对象没有 color 属性
let s2=new String("hello"); //s2既是对象,也是String类型的引用类型
s2.name="china";
console.log(s2.name); //china
//只要不离开这个作用域,这个实例就不会被销毁
3.如何创建原始值的包装对象?
//第一种方法:使用new 原始值构造函数
let str=new String('123');
//第二种方法:使用new Object构造函数
let str=new Object('123');
注意:所有原始值的包装对象都会转换为布尔值true
4.注意:
let str3=new String('123');
console.log(str3,typeof str3);//'123',Object
let str4=new Object('123');
console.log(str4,typeof str4);//'123',Object
//你是否也认为这两个对象相等?不不不,我们来看看下面!!!
if(str3==str4){
console.log("相等")
}else{
console.log("不相等")
}
//结果:不相等
???疑惑吗,别急,看看下面的解释
解析:如果两个变量的类型是基本数据类型,那么==比较的是两个变量的值
如果两个变量的类型是对象,那么==比较的是两个变量的地址【我们知道,对象本身是保存在
堆内存上的,而对象的访问时按引用访问的,两个不同的变量在堆内存上的位置怎么可能相同
呢】
二、Boolean对象
Boolean是对应布尔值的引用类型
1.如何创建一个Boolean对象?
语法:new Boolean(true/false);
例如:let bool=new Boolea(true);
// 使用object构造函数创建:let bool=new Object(false);
2.Boolean重写的方法
(1)Boolean对象会重写valueof()、toLocaleString()、toString(),返回原始值true或false
let bool=new Boolean(false);
let bool1=bool.valueOf();
let bool2=bool.toLocaleString();
let bool3=bool.toString();
//查看它们的值
console.log(bool1,bool2,bool3);//false 'false' 'false'
//查看他们的类型
console.log(typeof bool1,typeof bool2,typeof bool3);//boolean string string
3.注意:
(1)boolean对象在布尔表达式中容易引起误会,看下面:
let bool=new Boolean(false);
let bool2=bool&&true;
console.log(bool2);//true
是否感到差异,false&&true不应该等于false吗?
解析:前面我们提到过,所有对象的布尔值都会转换成true,所以这里的bool其实在运算时转换为true
(2)boolean对象在JS中用的很少,但是理解布尔原始值与布尔对象之间的区别非常重要,强烈建议永远不要使用布尔对象
2.Number对象
Number是对应数值的应用类型
1.如何创建一个Number对象?
语法:new Number(数值);
例如:let num=new Number(100)
// 使用object构造函数创建:let num=new Object(100);
2. Number重写的方法
(1)Number对象会重写valueof()、toLocaleString()、toString(),返回对应的原始值
let num=new Number(123);
let num1=num.valueOf();
let num2=num.toLocaleString();
let num3=num.toString();
//查看它们的值
console.log(num1,num2,num3); //123 '123' '123'
//查看他们的类型
console.log(typeof num1,typeof num2,typeof num3);//number string string
3. Number类型常用的一些方法有哪些?
(1)toFixed()方法
返回包含指定小数位数的数字字符串【你传入几,返回的数值就有几个小数位】
语法:Number变量.toFixed(数值)
例如:
let num=10;
console.log(num.toFixed(2));//"10.00"
//toFixed()返回的是字符串
let a=num.toFixed(2);
console.log(typeof a);//string
注意:如果数值本身的小数位数超过参数指定位数,则四舍五入到最接近的小数位
let num=3.14159;
console.log(num.toFixed(2));//"3.14"
(2).toExponential()方法
返回指定小数位的以科学计数法表示的数值字符串【你传入几,返回的数值就有几个小数位的科学计算法】
语法:Number变量.toExponential(数值)
例如:
let num=10;
console.log(num.toExponential(1));//"1.0e+1"
console.log(num.toExponential(2));//"1.00e+1"
(3)toPrecision()方法
根据情况返回最合理的输出结果,可能是固定长度,也可能是科学计数法形式,输入的参数表示返回结果的数字总位数
语法:Number变量.toPrecision(数值)
例如:
let num=99;
console.log(num.toPrecision(1));//"1e+2"
console.log(num.toPrecision(2));//"99"
console.log(num.toPrecision(3));//"99.0"
(4.) isInteger()方法
判断一个数值是否为整数,是返回true,不是返回false
语法:Number.isInteger(Number变量)
例如:
let num1=10.00;
let num2=10.01;
console.log(Number.isInteger(num1));//true
console.log(Number.isInteger(num2));//false
三、String对象
String是对应字符串的引用类型
1.如何创建一个String对象
语法:new String('值')
let str=new String("abc")
// 使用object构造函数创建:let str=new Object("abc");
2.string重写的方法
Boolean对象会重写valueof()、toLocaleString()、toString(),都返回对象的原始字符串值
let str1=new String("l love you");
let str2=str1.valueOf();
let str3=str1.toLocaleString();
let str4=str1.toString();
//查看它们的值
console.log(str1,str2,str3);//String {'l love you'}, "l love you" 'l love you', 'l love you'
//查看他们的类型
console.log(typeof str2,typeof str3,typeof str4);//string ,string ,string
3.JavaScript字符
每个string对象都有自己的length属性,用于表示字符串中字符的数量
let str=new String('ac');
let str2='ac';
console.log(str.length,str2.length)//2,2
JavaScript字符串是由16为码元组成的,每16位码元对应一个字符,换句话说,字符串的length属性表示字符串中含有多少个16位码元
4.string类型基础方法
(1)charAt()
返回给定索引位置的字符,由传给方法的整数参数决定【具体来说是查找指定所以的16位码元】
let str='abcde';
let str2=str.charAt(2);
console.log(str2);//c
console.log(typeof str2)//string
(2)charCodeAt()
查看指定索引的字符编码,返回对应的字符编码
let str='abcde';
let str2=str.charCodeAt(2);
console.log(str2);//99
(3)fromCharCode()
根据给定的字符编码创建字符串中的字符,返回拼接好的传入所以数值的字符
let str=String.fromCharCode(97,98,99,100);
console.log(str);//abcd
5.增补平面
为了表示更多的字符,Unicode采用了一种策略,即每个字符使用另外16位码元去选择一个增补平面,每个字符使用两个16位码元的策略称为代理对
在涉及到增补平面的字符时,前面的charAt(),charCodeAt(),fromCharCode()与length属性就会出现问题 ,16位只能唯一表示65536个字符,但是代理对有两个16位码元,其中一个超出了这个范围
let str='ab😊de';
//输出str长度
console.log(str.length);//6
//依次输出str字符
console.log(str.charAt(1));//a
console.log(str.charAt(2));//�
console.log(str.charAt(3));//�
console.log(str.charAt(4));//d
//一次输出字符的字符编码
console.log(str.charCodeAt(1));//98
console.log(str.charCodeAt(2));//55357
console.log(str.charCodeAt(3));//56842
console.log(str.charCodeAt(4));//100
//输出笑脸【字符编码:0x1F60A】
console.log(String.fromCodePoint(0x1F60A));//😊
console.log(String.fromCharCode(0x1F60A));//
解析:这里我们可以看到增补平面在被length,charAt(),charCodeAt(),formCharCode()调用时均
会表现错误,这些方法仍然将16位码元当作一个字符他们将代理对的2个16位码元当作了两个字符
上面代码fromCharCode无法输出代理对字符,是因为代理对是2个16位码元的字符,所以如果想用fromCharCode输出代理对,应该在传入字符编码时将两个字符编码都传进去,显然这样非常的麻烦
console.log(String.fromCharCode(55357,56842));//😊
6.string基于代理对字符的方法
(1)codePointAt()
和charCodeAt()类似,返回指定索引的字符的字符编码【这里之一前面的charCodeAt()返回代理对编码时虽然也可以返回两个编码,但是有一个时错误的】
【介绍这里之前,给大家说一下码点 的概念】
码点:一个字符的完整标识,一个字符的码点可能时16位的,也可能时32位的,比如代理对就是32位的
let str='ab😊de';
console.log(str.codePointAt(1));//98
console.log(str.codePointAt(2));//128522
console.log(str.codePointAt(3));//56842
console.log(str.codePointAt(4));//100
//这样就可以正确的返回字符编码了
(2)fromCodePoint()
根据给定的字符编码创建字符串中的字符,返回拼接好的传入所以数值的字符【可以传入任何数值】
console.log(String.fromCodePoint(97,98,128522,100,101));//ab😊de
console.log(String.fromCharCode(97,98,55357,56842,100,101));//ab😊de
//是否感觉fromCharCode非常的麻烦
7.string常用方法(整合)
1.字符串操作方法
(1)concat()
组合【多个】字符串,返回组合后的字符串
let str='hello';
let str2=str.concat('world');
let str3=str.concat('world','!')
console.log(str2);//helloworld
console.log(str3);//helloworld!
(2)substr()
根据下标截取指定的字符串,第一个参数表示开始位置,第二个表示从开始位置截取多少个【空格也算一个字符】
let str='my name is kangkang'
let str2=str.substr(3,7);
console.log(str2);//name is
(3)substring()
根据指定的下标范围截取字符串,第一个参数表示起始下标,第二个表示结束下标,但是结束下标的字符不包含在字符串里面,结束下标可以省略,省略表示截止末尾
//substring()
let str='my name is kangkang';
let str2=str.substring(3,10);
console.log(str2);//name is
(4)split()
根据指定字符分割字符串,字符必须是字符串中已有的字符
let str="ab,cd,ef";
console.log(str.split(","));//(3) ['ab', 'cd', 'ef']
2.字符串位置方法
(1)indexOf()
获取指定字符的下标,可以传入两个参数,第一个参数表示需要寻找的字符,第二个参数表示从哪里开始寻找【这个开始位置之前的字符将不会被检查,且默认为0】,寻找顺序时从前往后,没找到返回-1
//indexOf()
let str='hello world';
console.log(str.indexOf("o"));//4
console.log(str.indexOf("o",6));//7
(2)lastindexOf()
获取指定字符的下标,可以传入两个参数,第一个参数表示需要寻找的字符,第二个参数表示从哪里开始寻找【这个开始位置之后的字符将不会被检查】,寻找顺序是从后往前,没找到返回-1
let str='hello world';
console.log(str.lastIndexOf("o"));//7
console.log(str.lastIndexOf("o",6));//4
3.字符串包含方法
(1)startsWith()
检查一个字符串中是否包含另一个字符串,只能传入一个参数,从索引0开始检查,有返回true,没有返回false
let str='name is wy';
console.log(str.startsWith("name"));//true
console.log(str.startsWith("is"));//false
(2)endsWith()
检查一个字符串中是否包含另一个字符串,只能传入一个参数,从string.length-substring.length处开始检查,有返回true,没有返回false
let str1='name is wy';
console.log(str.endsWith("wy"));//true
console.log(str.endsWith("n"));//false
(3)includes() (推荐)
检查一个字符串中是否包含另一个字符串,只能传入一个参数,检查整个字符串,有返回true,没有返回false
let str2='name is wy';
console.log(str.includes("name"));//true
console.log(str.includes("wy"));//true
console.log(str.includes("dog"));//false
4.trim()
创建字符串的一个副本,清除字符串前后所有空格,返回副本
let str=' hello world ';
let str2=str.trim();
console.log(str);// hello world
console.log(str2);//hello world
此外,trimLeft()与trimRight()分别用于清除字符串开始与结尾的空字符,并返回副本
5.repeat()
表示将字符串复制多少次,然后返回拼接所有副本的结果
let str='na ';
let str2=str.repeat(5)+"love";
console.log(str2);//na na na na na love
6.padStart()与padEnd()
padStart():首先复制字符串,可以传入两个参数,第一个参数指定长度,第二个参数为填充字符,如果复制的字符串length小于指定的长度,在前面填充字符,如果大于则输出原字符串。没有指定填充字符默认为空格
padEnd():首先复制字符串,可以传入两个参数,第一个参数指定长度,第二个参数为填充字符,如果复制的字符串length小于指定的长度,在后面填充字符,如果大于则输出原字符串。没有指定填充字符默认为空格
let str='foo';
let str2=str.padStart(6);// foo
let str3=str.padStart(6,'.');//...foo
let str4=str.padStart(2);//foo
let str5=str.padEnd(6);//foo
let str6=str.padEnd(6,'.');//foo...
let str7=str.padEnd(2);//foo
7.字符串的迭代与解构
迭代:for-of语句【按顺序访问每一个字符】
let str='abcd';
for(const STR of str){
console.log(STR);
}
//a
//b
//c
//d
解构:把字符串分割为字符数组
let str='abcdefg';
let str2=[...str];
console.log(str2);//["a","b","c","d"]
8.字符串大小写转换
涉及到大小写转换JS中有四种方法,分别是toLowerCase(),toUpperCase()与toLocaleLowerCase(),toLocalUpperCase() 。前面两种是我们常用的两种方法,后面两种主在基于特定地区实现【例如在土耳其语言中,大小写的转换需要应对特殊规则】,如果你不知道代码中的语言,则最好使用后面两种方法
let str='abcde';
console.log(str.toUpperCase());//ABCDE
console.log(str.toLocaleUpperCase())//ABCDE
let str2="ABCDE";
console.log(str2.toLowerCase());//abcde
console.log(str2.toLocaleLowerCase())//abcde
9.字符串模式匹配
字符串模式匹配在上章2-2.4已经给大家介绍了。点击此处查看
8.扩展-normalize()
将一个字符的多种编码方式规范为一致格式
某些Unicode字符可以有多种编码方式,有的字符既可以通过一个BMP【基本多语言平面,一个字符只用1个16位码元表示就是一个BMP字符】字符表示,也可以通过一个代理对表示。比如:
console.log(String.fromCharCode(0x00C5));//Å
console.log(String.fromCharCode(0x212B));//Å
console.log(String.fromCharCode(0x0041,0x030A));//Å
比较操作符不在意这三个字符看起来长什么样,因此他们互不相等【编码不同】
let str=String.fromCharCode(0x00C5);
let str2=String.fromCharCode(0x212B);
let str3=String.fromCharCode(0x0041,0x030A);
console.log(str==str2,str==str3,str2==str3);//false false false
为解决这个问题,Unicode提供了四种规范形式,可以将类似上面的字符 规范为一致格式,分别为NFD、NFC、NFKD、NFKC。可以使用normalize()方法对字符串应用这四种格式
let str=String.fromCharCode(0x00C5);
let str2=String.fromCharCode(0x212B);
let str3=String.fromCharCode(0x0041,0x030A);
let a1=str.normalize("NFD");
let a2=str2.normalize("NFD");
let a3=str3.normalize("NFD");
console.log((a1==a2,a2==a3,a3==a1));//true,true,true
注意:console.log(a1==a2==a3);//false 至于为什么这样目前我尚不知道
四、Global对象
一个固有对象,目的是把所有全局方法集中在一个对象中。Global 对象不能用 new 运算符创建。它在 Scripting 引擎被初始化时创建,并立即使其方法和属性可用。
1.URL编码方法
(1)encodeURI()和encodeURIComponent()
编码统一资源标识符(URI),不能包含某些字符,以便传给浏览URI地址【个人觉得就是加密地址】
encodeURI():不会编码属于URI组件的特殊字符。比如冒号、斜杠、问号
encoIURIComponent():编码所有非URI标准字符
let str="www.baidu.com/value a";
console.log(encodeURI(str));
console.log(encodeURIComponent(str));
//www.baidu.com/value%20a
//www.baidu.com%2Fvalue%20a
(2)decodeURI()与decodeURIComponent()
解码
decodeURI():只解码encodeURI()编码过的字符
decodeURIComponent():解码所有被encodeURIComponent()编码过的字符
// let str="www.baidu.com/value a";
// console.log(encodeURI(str));//www.baidu.com/value%20a
// console.log(encodeURIComponent(str));//www.baidu.com%2Fvalue%20a
let str='www.baidu.com/value%20a'
console.log(decodeURIComponent(str));
console.log(decodeURI(str))
//www.baidu.com/value a
//www.baidu.com/value a
decodeURIComponent()基本可以解码所有的特殊值
2.eval()
eval()函数会将传入的字符串当做 JavaScript 代码进行执行。
语法:eval(string)
console.log(eval('2 + 2'));
// expected output: 4
console.log(eval(new String('2 + 2')));
// expected output: 2 + 2
console.log(eval('2 + 2') === eval('4'));
// expected output: true
console.log(eval('2 + 2') === eval(new String('2 + 2')));
// expected output: false
当后端传送的数据本应该是一个数组的时候,后端采用字符串的方式传送过来,我们可以调用eval方法。
但是!!
永远不要使用 eval!
eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。
eval() 通常比其他替代方法更慢,因为它必须调用 JS 解释器,而许多其他结构则可被现代 JS 引擎进行优化。
此外,现代JavaScript解释器将javascript转换为机器代码。 这意味着任何变量命名的概念都会被删除。 因此,任意一个eval的使用都会强制浏览器进行冗长的变量名称查找,以确定变量在机器代码中的位置并设置其值。 另外,新内容将会通过 eval() 引进给变量, 比如更改该变量的类型,因此会强制浏览器重新执行所有已经生成的机器代码以进行补偿。 但是,(谢天谢地)存在一个非常好的eval替代方法:只需使用 window.Function。
所以使用eval的时候尽量不要传入代码, 而是传入数据。例如数组字符串,json。
3.window对象
ECMA-262中没有直接访问Global对象的方式,但是浏览器将window对象实现为Global对象的代理。
所有在全局作用域中用var定义的变量与函数都是window的属性
五、Math对象
保存数学公式,信息和计算的地方
1.min()和max()方法
取一组数值中的最大值与最小值
console.log(Math.min(12,2));//2
console.log(Math.max(12,1));//12
当两个都只传入一个相同数值时候两个返回值相等 例如Math.max(12)==Math.min(12)
2.Math.random()
生成0-1之间的随机数
let num=Math.random();
console.log(num)//0.3087906875652493
3.Math.ceil(x)
对x向上取整,忽略小数位,整数位+1
let num=Math.random();
let num2=Math.ceil(num);
console.log(num)//0.3087906875652493
console.log(num2);//忽略小数位,整数位+1
4.Math.floor(x)
对x向下取整,舍弃小数位,保留整数位
let num=10.99;
console.log(Math.floor(num));//10
5.Math.round(x)
对x四舍五入取整数
let num=3.54;
let num2=3.14;
console.log(Math.round(num));//4
console.log(Math.round(num2));//3
这章的内容就到这里了吧,不知不觉写下来字已过万,主要是对于String的方法描述较多,掌握这些方法对我们日后处理字符串有什么很好的帮助。下期见伙计们
