2022.3.25 学习笔记
目录
2.5.4 数组排序
2.5.5 数组索引方法
案例:数组去重
function unique(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) { //遍历旧数组
if (newArr.indexOf(arr[i]) == -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']);
console.log(demo); // 输出[ "c", "a", "z", "x", "b" ]
2.5.6 数组转换为字符串
2.5.7 补充
2.6 字符串对象
2.6.1 基本包装类型
为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:String、Number和 Boolean。
基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。(只有复杂数据类型才有属性和方法)
// 下面代码有什么问题?
var str = 'andy';
console.log(str.length);
按道理基本数据类型是没有属性和方法的,而对象才有属性和方法,但上面代码却可以执行,这是因为 js 会把基本数据类型包装为复杂数据类型,其执行过程如下 :
// 1. 生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('andy');
// 2. 赋值给我们声明的字符变量
str = temp;
// 3. 销毁临时变量
temp = null;
2.6.2 字符串的不可变
指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
var str = 'abc';
str = 'hello';
// 当重新给 str 赋值的时候,常量'abc'不会被修改,依然在内存中
// 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
// 由于字符串的不可变,在大量拼接字符串的时候会有效率问题
var str = '';
for (var i = 0; i < 100000; i++) {
str += i;
}
console.log(str); // 这个结果需要花费大量时间来显示,因为需要不断的开辟新的空间
2.6.3 根据字符返回位置
字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。
案例:返回字符位置
查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数。
(查找数组中的某项数组元素也可以用此方法)
var str = 'abcoefoxyozzopp';
function research(str) {
var location = str.indexOf('o');
var num = 0;
while (location !== -1) {
console.log(location); //由于第一个o出现的位置没有打印,因此此行代码写在最前面
num++;
location = str.indexOf('o', location + 1)
}
console.log('o出现的次数为' + num);
}
research(str);
2.6.4 根据位置返回字符(重点)
案例: 返回字符位置
判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数。
知识铺垫:1.当对象中不存在某项属性时,obj['属性名']默认值为undefined。
var obj={
age:18
}
console.log(obj['sex']); //输出undefined
2.如下例,在进行布尔判断时,当对象中不存在某项属性时,obj['属性名']的值为undefined会被视为false;当对象中不存在某项属性时,obj['属性名']的值会被视为true。
var obj={
age:18
}
if (obj['age']){
console.log('该对象中存在该属性');
}else{
console.log('该对象中没有该属性');
}//输出 该对象中存在该属性
①② var str = 'abcoefoxyozzopp';
var obj = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i); / chars是一个变量,指得是str里的每一个字符,因此判断obj是否存在chars属性时只能写成obj[chars],不能写成obj['chars'],也不能写成obj.chars
if (obj[chars]) { // obj存在chars属性
obj[chars]++;
} else { // obj不存在chars属性
obj[chars] = 1; // 设置obj[chars]的属性值为1
}
}
console.log(obj);
③遍历obj,得到最大值和该字符
var max = 0; //在本例中obj[k]最小为1
var charr = '';
for (var k in obj) {
if (max < obj[k]) {
max = obj[k]; //obj[k]得到属性值
charr = k; //k得到属性名
}
}
console.log('出现最多的字符是'+charr);
console.log('出现的次数为'+max);
2.6.5 字符串操作方法(重点)
2.6.6 replace()方法
replace() 方法用于在字符串中用一些字符替换另一些字符。
其使用格式如下: replace(被替换的字符串, 要替换为的字符串); 只会替换第一个字符
2.6.7 split()方法
split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。
例如下面代码:
var str = 'a,b,c,d';
console.log(str.split(',')); // 返回的是一个数组 [a, b, c, d]
2.6.8 补充
1. toUpperCase() //转换大写
2. toLowerCase() //转换小写
三、JavaScript简单数据类型和复杂数据类型
3.1 简单数据类型与复杂数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
1. 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型。string ,number,boolean,undefined,null。
2. 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等。
3.2 堆和栈
堆栈空间分配区别:
1. 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面。
2. 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型存放到堆里面。
注意:JavaScript中没有堆栈的概念,通过堆栈的方式,可以让大家更容易理解代码的一些执行方式,便于将来学习其他语言。
3.3 数据类型的内存分配
1. 值类型变量的数据直接存放在变量(栈空间)中
2. 引用类型变量(栈空间)里存放的是地址(用十六进制表示),真正的对象实例存放在堆空间中
3.4 简单类型传参
函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。
function fn(a) { //a=x=10
a++;
console.log(a); //11
}
var x = 10;
fn(x);
console.log(x);//10
3.5 复杂类型传参
函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。
function Person(name) {
this.name = name;
}
function f1(x) { // x = p 即让x指向的地址等于p指向的地址,x和p指向同一个地址
console.log(x.name); // 2. 这个输出什么 ? 刘德华
x.name = "张学友";
console.log(x.name); // 3. 这个输出什么 ? 张学友
}
var p = new Person("刘德华");
console.log(p.name); // 1. 这个输出什么 ? 刘德华
f1(p);
console.log(p.name); // 4. 这个输出什么 ? 张学友