输入输出
<script>
// 输入框,取值为String类型
prompt('请输入');
// 在文档中输出,可识别标签
document.write('要输出的内容');
// 弹出警示框
alert("结果");
// 控制台输出,给程序员测试用的
console.log('我是程序员能看到的!');
</script>
变量
关键词var
注意:不声明直接赋值也可以输出结果;
尽量不要使用name命名变量名;
弱类型,根据后边的值来确定;
变量的数据类型可以变化;
undefined和数字相加是NaN(非数字)。
var和let的区别
区别:
1.使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
2.使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
3.let不允许在相同作用域内,重复声明同一个变量
const
(1) const是设置常量,也就是不能改变。const定义的数值字符串的时候值不能改变。
(2) const 定义的对象的时候,对象不能改变,但是对象的属性值可以改变。
常见面试题
<script>
for (var i = 0; i <10; i++) {
setTimeout(function() { // 同步注册回调函数到 异步的 宏任务队列。就是程序结束才调用
console.log(i); // 执行此代码时,同步代码for循环已经执行完成
}, 0);
}
// 输出结果
//10 共10个
// i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。
for (let i = 0; i < 10; i++) { // 被固化
setTimeout(function() {
console.log(i); // i 是循环体内局部作用域,不受外界影响。
}, 0);
}
// 输出结果:
// 0 1 2 3 4 5 6 7 8 9
</script>
变量简单数据类型
可以用typeof检测数据类型
var str='my name is ssy';
console.log(typeof str);
Number类型
前边加0为八进制,前边加0x是十六进制;
最大值Number.MAX_VALUE,最小值Number.MIN_VALUE;
无穷大(Infinity)Number.MAX_VALUE*2;
无穷小(-Infinity)-Number.MAX_VALUE*2;
NaN表示非数值,
isNaN();//判断是否是非数字,是数字返回false,否则返回true。
String类型
1、引号就近匹配,可以配合单双引号使用;
2、字符串转义符
3、字符串拼接‘+’
数值相加,字符相连
混合显示字符串
Boolean类型
变量声明为true或false,运算时true当1,false当0
数据类型替换
转化为字符串类型
//1.把数字类型转化为字符串类型,变量.toString();
var num1 = 10;
var str2 = num1.toString(); //数组也可以
console.log(str2);
console.log(typeof str2);
//2.利用String(变量)
console.log(String(num1));
//3.利用+拼接字符串
console.log(num1 + '');
转化为数字型
//把字符串类型转化为数字类型
var age1 = prompt('请输入你的年龄');
//1.parseInt(变量),得到的是整数(去尾,可以去单位)
console.log(parseInt(age1));
console.log(typeof age1);
console.log(parseInt('1.23'));//1
console.log(parseInt('123px'));//123
console.log(parseInt('abc123px'));//NaN(非数字)
//2.parseFloat(变量),得到小数、浮点数(也可以去单位)
console.log(parseFloat(age1));
console.log(typeof age1);
console.log(parseFloat('1.23'));//1.23
console.log(parseFloat('123px'));//123
console.log(parseFloat('abc123px'));//NaN(非数字)
//3.利用Number(变量)强制转化
console.log(Number(age1));
console.log(typeof age1);
console.log(Number('1.23'));//1.23
//4.利用算术运算(- * /)没有+,隐式转化
console.log('123' - 0);//123
console.log('123' - '0');//123
转化为布尔类型
- 代表空、否定的值会被转化为false,如‘ ’、0、NaN、null、undefined
- 其余值都会被转化为true
//转化为布尔类型
console.log(Boolean(''));//false
console.log(Boolean(0));//false
console.log(Boolean(NaN));//false
console.log(Boolean(null));//false
console.log(Boolean(undefined));//false
console.log('--------------');
console.log(Boolean(123));//true
console.log(Boolean('hhh'+123));//true
console.log(Boolean('123'));//true
console.log(Boolean('呵呵'));//true
console.log(Boolean('hhh'));//true
算数运算符
1、浮点数计算会有误差;
2、不能拿浮点数进行比较,判断是否相等。
3、前置递增,后置递增
4、==默认转化字符类型
5、===全等(一模一样),!==不全等
6、短路运算符(逻辑中断)
①逻辑与&&中断
//1.用布尔值参与运算 true && false == false
//2.123 && 456 是值 或者是 表达式 参与逻辑运算?
//3.逻辑与短路运算 如果表达式1 结果为真 则返回表达式2 如果表达式1为假 那么返回表达式1
console.log(123 && 456); //456
console.log(0 && 456); //0
console.log(0 && 1 + 2 && 456 * 1234); //0
console.log('' && 1 + 2 && 456 * 1234); //''
//如果有空或者否定的为假 其余是真 0 '' null undefined NaN
②逻辑或||中断(重要)
//4.逻辑或短路运算 如果表达式1 结果为真 则返回表达式1 如果表达式1为假 那么返回表达式2
console.log(123 || 456); //123
console.log(123 || 456 || 123 + 456); //123
console.log(0 || 456 || 123 + 456); //456
var num1 = 0;
console.log(123 || num1++);
console.log(num1);//0
流程控制
顺序控制
略
分支控制
1、if{}else{}
2、三元表达式
条件表达式 ? 表达式1 : 表达式2
3、switch语句
switch(表达式){
case value1:
执行语句1;
break;
case value2:
执行语句1;
break;
...
default:
最后语句;
}
循环控制
1、for循环(可以嵌套)
语法:
for(初始化变量; 条件表达式;操作表达式){
循环体;
}
嵌套例子:
//倒三角
var str1 = '';
for(var i = 1; i <= 10; i ++){
for(var j = i; j <= 10; j++){
str1 = str1 + '1';
}
str1 = str1 + '\n';
}
console.log(str1);
//九九乘法表
var str2 = '';
for(var i = 1;i <= 9; i++){
for(var j = 1; j <= i; j++){
str2 += j + 'x' + i + '=' + i * j + '\t';
}
str2 += '\n';
}
console.log(str2);
2、while循环
语法:
while (条件表达式) {
循环体;
//应该有计数器操作表达式
}
例子:
var message1 = prompt('你爱我吗?');
while (message1 !== '我爱你' && message1 !== '爱你' && message1 !== '爱') {
message1 = prompt('你爱我吗?');
}
alert('我也爱你呀!');
3、do while循环
语法:
//先执行循环体,再判断
do {
循环体;
//应该有计数器操作表达式
} while (条件表达式)
例子:
do {
var message2 = prompt('真的吗?')
} while(message2 !== '真的' && message2 !== '真')
alert('那我去找你了!');
continue和break
1、contnue
跳出当前循环,执行下一次
2、break
跳出整个循环
综合案例
简单银行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简单银行</title>
</head>
<script>
var sum = 100;
do {
var num = prompt('请输入您要进行的操作:\n1.存钱\n2.取钱\n3.显示余额\n4.退出');
switch (num) {
case '1':
var sum1 = prompt('请输入要存存款:');
sum += parseFloat(sum1);
alert('你现在余额为:'+sum);
break;
case '2':
var sum2 = prompt('请输入要取存款:');
sum -= parseFloat(sum2);
alert('你现在余额为:'+sum);
break;
case '3':
alert('你现在余额为:'+sum);
break;
case '4':
alert('您正在退出!');
break;
default:
num = prompt('请输入您要进行的操作:\n1.存钱\n2.取钱\n3.显示余额\n4.退出');
}
} while(num !== '4')
</script>
<body>
</body>
</html>
数组(array)
!不要直接给数组名赋值,否则里边的数组元都会没有
1、创建数组
①利用new创建数组
var arr = new Array();//创建了一个空的数组
var arr1 = new Array(3);//长度为3,内容为空
var arr2 = new Array(1,2,3);//创建数组并赋值
②利用数组字面量创建数组(常用)
var arr = [];//创建了一个空数组,数据用‘,’分隔
③初始化
arr = [1, 'asa', true];//可以放任意类型
2、访问数组
根据索引访问
console.log(arr[num]);//num为索引号,索引号默认从0开始
//超出部分输出undefined
3、遍历数组
①可以根据索引号利用循坏遍历
数组长度:
arr.length;//动态监测数组长度—>元素个数
②forEach 方法
无法在中间停止
数组名.forEach((item, index) => {}); // item代表数组的每一项,index代表索引
③ some 方法
可以通过 return true; 跳出
数组名.some((item, index) => {}); // item代表数组的每一项,index代表索引
④ array 方法
判断数组中,水果是否被全选
let arr = [
{ id: 1, name: '西瓜', state: true},
{ id: 2, name: '黄瓜', state: false},
{ id: 3, name: '草莓', state: true},
]
let result = arr.every(item => item.state) // item => item.state 是判断条件 返回true 或者 false
console.log(result); // false
⑤ reduce 方法和 filter 过滤器
循环数组,可以计算累加和
数组.reduce((累加结果, 当前循环项) => {}, 初始值)
数组.filter(item => 判断条件) // 过滤器,返回符合条件的数组元素
let arr = [
{ id: 1, name: '西瓜', state: true, price: 10, count: 1},
{ id: 2, name: '黄瓜', state: false, price: 5, count: 2},
{ id: 3, name: '草莓', state: true, price: 20, count: 3},
]
// 把购物车数组中,已勾选的水果,总价累加起来
/* let amt = 0 // 总价
arr.filter(item => item.state).forEach(item => {
amt += item.prive * item.count
})
console.log(amt) */
// arr.filter(item => item.state).reduce((累加结果, 当前循环项) => {}, 初始值)
arr.filter(item => item.state).reduce((amt, item) => { // 箭头函数只有一行代码可以省略{}
return amt += item.price * item.count; // amt 为累加上一次的和
}, 0)
⑥ find 方法
查找对应项
数组名.find(item => {判断条件}); // item代表找出对应每一项
4、新增元素
①通过修改length长度新增数组元素
修改后新增部分里边为空,默认是undefined
②通过修改索引号增加数组元素
直接根据索引新增或者替换
var arr = [2,4,23,32,12,35,50,3,6,9];
var newArr = [];
//刚开始 newArr.length 就是0
for (var i = 0; i<arr.length; i++) {
if (arr[i] >= 10) {
//新增数组索引号应该从0开始,依次递增
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
可以新建数组来进行替换删除操作等等
5、冒泡排序
//冒泡排序
var arr = [5,12,21,3,4,6,9,2,2,1]
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j <= arr.length-i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr [j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
函数
封装了重复使用的代码块
步骤:
①声明
// 1、function声明函数
function 函数名() { // 函数名一般为动词
//函数代码
}
//2、函数表达式,匿名函数
var 变量名 = function(参数){
//代码
}
//只能在后边调用
变量名(参数);
②调用
// 调用函数
函数名();
③函数返回值
通过return(也会终止函数)返回;
多个返回值,只返回最后一个值;可以通过数组返回多个值;
函数如果没有返回值(没有return),函数返回undefined。
=> 箭头函数
区别:
1.箭头函数与普通函数写法不同
//箭头函数
//var声明变量时
var fn = (a, b)=>{
return a+b};
//let声明变量时
let foo = () => {
console.log('foo');
}
//function 普通函数
//上述var等同于
function fn(a, b) {
return a+b;
}
//上述let等同于
function foo() {
console.log('foo');
}
2.This的指向不同(最重要!!!)
使用function定义额函数,this的指向随着调用环境的变化而变化,而箭头函数=>中this的指向是固定不变的:
//使用function定义的函数
function foo() {
console.log(this);
}
var obj = { aa : foo};
foo(); //window
obj.aa(); //obj { aa : foo}
//使用箭头函数=>定义的函数
var foo = () => { console.log(this)};
var obj = {aa : foo};
foo(); //window
obj.aa(); //window (箭头函数的this指向固定不变)
123456789101112
3.变量提升
由于Js的内存机制,function的级别最高,使用箭头函数定义函数时,需要使用var/let/const关键词,而let和const不存在变量提升(var、let和const的区别)
4.箭头函数不可以当做构造函数,不可以使用new命令,否则会报错,如下:
//尝试使用箭头函数定义构造函数
var Person = (name, age) => {
this.name = name;
this.age = age;
};
var lenhart = new Person('lenhart', 25); //Uncaught TypeError: Person is not a constructor
//使用function方法定义构造函数
var Person = (name, age) => {
this.name = name;
this.age = age;
};
var lenhart = new Person('lenhart', 25);
console.log(lenhart); //{name: 'lenhart', age: 25}
1234567891011121314
4.箭头函数不可以使用arguments对象,该对象在函数体内不存在;如果要用,可以用Rest参数代替。
5.箭头函数不可以使用yield命令,因此箭头函数不能用作Generator函数。
形参,实参
声明的时候是形参;
调用的时候是实参;
可有可无;
如果个数不匹配
实参>形参,会取到形参个数
实参<形参,多余的形参定义为undefined,最总结果为NaN
arguments
当不知道用户传过来的实参个数时,可以用js函数的内置对象arguments,arguments对象存储了所有的实参,它的展示形式是伪数组,只有函数可以用。
//利用函数求任意个数的最大值
function getMax(){
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1, 2, 3, 4, 5));
console.log(getMax(12, 23, 34, 45, 56));
console.log(getMax(12, 13, 3, 3, 0));
伪数组
特点:
①具有length属性
②按照索引方式进行存储,可以循环遍历
③他没有真正数组的一些方法pop()、push()等等
作用域
代码名字(变量)在某个范围内起作用和效果,提高可靠性,减少命名冲突
全局作用域
整个script标签或者js文件内有效,浏览器关闭才销毁,比较占内存
全局变量:在全局作用域内有效 //如果在函数内部没有声明,直接定义的变量,也属于全局变量👀
局部作用域
函数内部定义的,函数内部有效,当程序执行完毕就会销毁,比较节约内存
局部变量:在局部作用域下有效 //函数的形参也可以看作为局部变量
块级作用域
在{}中声明的,现阶段没有,在es6新增了
作用域链
内部函数访问外部函数的变量,采取的是链式查找的方法来决定取哪个值(就近原则)
var num = 10;
function fn() {
var num = 20;
function fun() {
console.log(num) //20
}
fun();
}
fn();
预解析
1、js 引擎会把 js 里面所有的 var 和 function 提到最前边
2、代码执行 按照代码书写顺序从上向下执行
面试常问🐱🐉
变量预解析(变量提升)
把所有的变量声明提升到当前作用于最前面,不提升赋值操作
console.log(num); //undefined
var num = 10;
fun();
var fun = function() {
console.log(10) //报错
}
函数预解析(函数提升)
把所有的函数声明提升到当前作用于最前面,不调用函数
fun();
function fun() {
console.log(10) //10
}
案例
//预解析,变量函数提升案例(面试)
f1();//9 9 9
console.log(c); //9
console.log(b); //9
console.log(a); //报错
function f1() {
var a = b = c = 9; //相当于 var a = 9; b = 9; c = 9; b 和 c 直接赋值,内有var声明,相当于全局变量
console.log(a); //9
console.log(b); //9
console.log(c); //9
}
//相当于
function f1() {
var a;
a = 9;
b = 9; //全局变量
c = 9; //全局变量
console.log(a); //9
console.log(b); //9
console.log(c); //9
}
f1();
console.log(c); //9
console.log(b); //9
console.log(a); //报错
对象
一组无序的相关属性和方法的集合,所有事物都是对象
创建和调用对象
//1、创建对象
var obj1 = {}; //创建了一个空的对象
var obj2 = { //里面的属性或方法采用键值对的形式书写 键 属性名:值 属性值;
uname: 'ssy', //用 , 隔开;
age: 23,
sex: '男',
sayHi: function() { //方法冒号后边是匿名函数
console.log('Hi!');
}
}
//2、使用对象
console.log(obj2.uname); //(1)调用对象属性,采用 对象名.属性名;
console.log(obj2.age); //(2)调用对象属性,采用 对象名['属性名'];
obj2.sayHi(); //(3)调用对象方法,采用 对象名.方法名();
//3、利用 new Object创建对象
var obj3 = new Object(); //创建了一个空的对象
obj3.uname = 'ssy2';//利用 等号 = 赋值的方法添加对象属性和方法
obj3.age = 23; //用分号 ; 结束
obj3.sex = '男';
obj3.sayHi = function() { //方法冒号后边是匿名函数
console.log('Hi!');
}
console.log(obj3.uname); //(1)调用对象属性,采用 对象名.属性名;
console.log(obj3.age); //(2)调用对象属性,采用 对象名['属性名'];
obj3.sayHi(); //(3)调用对象方法,采用 对象名.方法名();
//4、利用构造函数创建对象
//就是把对象里边一些相同的属性和方法抽象出来封装到函数里边
/* function 构造函数名() {
this.属性 = 值;
this.方法 = function() {}
}
new 构造函数名(); */
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var obj4 = new Star('ssy3', 23, '男');
console.log(typeof obj4); //object
console.log(obj4.name); //ssy3
console.log(obj4['age']); //23
obj4.sing('歌曲1'); //歌曲1
var obj5 = new Star('ssy4', 24, '男');
console.log(typeof obj4); //object
console.log(obj5.name); //ssy4
console.log(obj5['age']); //24
obj5.sing('歌曲2'); //歌曲2
//(1)构造函数的名字首字母要大写
//(2)构造函数不需要return就可以返回结果
//(3)调用构造函数必须使用 new
//(4)只要new Star() 调用函数就创建一个对象 obj {}
//(5)属性和方法前边必须添加 this
遍历对象
for in 遍历
//for(变量 in 对象) {}
for (var k in obj) {
console.log(k); // k变量 输出 得到的是属性名
console.log(obj[k]); // obj[k] 得到的是属性值
}
变量、属性;函数、方法的区别
构造函数和对象的区别
略
new关键字
内置对象
js中有:自定义对象、内置对象、浏览器对象
内置对象常用有:Math、Date、Array、String等。
查文档
可以通过查文档学习内置对象,可以通过MDN/W3C来查询
MDN:https://developer.mozilla.org/zh-CN/
可以自己封装对象
var obj = { //里面的属性或方法采用键值对的形式书写 键 属性名:值 属性值;
PI: 3.141592653, //用 , 隔开;
sayHi: function() { //方法冒号后边是匿名函数
console.log('Hi!');
}
}
Math对象
取整:Math.floor(); Math.ceil(); Math.round();
Math.random() : 返回[0,1)范围内随机浮点数,无参;
随机整数:Math.floor(Math.random() * (max - min + 1)) + min;
Date对象
Date() : Date()日期对象 是一个构造函数,必须用new来调用;
无参数时 为当前时间;
字符串格式 ‘2023-4-9 12:48:12’;
数字格式 2023, 4, 9 返回的是5月;
//Date()日期对象 是一个构造函数,必须用new来调用
var date1 = new Date();
var date2 = new Date('2023-4-9 12:48:12');
var date3 = new Date(2023, 4, 9);
console.log(date1); //返回当前时间
console.log(date2); //正常
console.log(date3); //返回的是5月,不是4月
var date4 = new Date();
console.log(date4.getFullYear()); //返回当前年份
console.log(date4.getMonth() + 1); //返回当前月份,返回月份默认从0开始,记得加1
console.log(date4.getDate()); //返回当前几号
console.log(date4.getDay()); //返回当前星期,从 星期日到星期六 依次是 0,1,2,3,4,5,6
console.log(date4.getHours()); //时
console.log(date4.getMinutes()); //分
console.log(date4.getSeconds()); //秒
var year = date4.getFullYear();
var month = date4.getMonth() + 1; //加1
var dates = date4.getDate();
var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day = date4.getDay();
console.log('当前日期是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]);
function getTime() {
var time = new Date();
var h = time.getHours(); //时
h = h < 10 ? '0' + h : h; //小于10,前边补0
var m = time.getMinutes(); //分
m = m < 10 ? '0' + m : m; //小于10,前边补0
var s = time.getSeconds(); //秒
s = s < 10 ? '0' + s : s; //小于10,前边补0
return h + '时' + m + '分' + s + '秒';
}
console.log(getTime()); //00时00分00秒
时间戳(总的毫秒数)
//获取总的毫秒数(时间戳),距离1970年1月1日过了多少毫秒
//1、通过valueOf() 或者 getTime() 获取
var date5 = new Date();
console.log(date5.valueOf());
console.log(date5.getTime());
//2、简单写法(常用)
var date6 = +new Date();
console.log(date6);
//3、H5新增的方法
console.log(Date.now());
倒计时
//1、核心算法:输入的时间减去现在的时间就是剩余时间,即倒计时,但是不能拿着时分秒直接相减
//2、用时间戳来做,用户输入的时间的总毫秒数减去现在时间的总毫秒数,得到剩余时间的总毫秒数
//3、把剩余时间总毫秒数转化为天、时、分、秒(时间戳转化为时分秒)
//转化公式如下:
// d = parseInt(总秒数/ 60/60 /24); //计算天数
// h = parseInt(总秒数/ 60/60 %24); //计算小时
// m = parseInt(总秒数/ 60/60 /24); //计算分数
// s = parseInt(总秒数/ 60 %60); //计算当前秒数
function countDown(time) {
var nowTime = +new Date(); //当前时间的总毫秒数
var inputTime = +new Date(time); //用户输入时间的总毫秒数
var times = (inputTime - nowTime) / 1000; //剩余时间总秒数
var d = parseInt(times / 60 / 60 / 24); //计算天数
d = d < 10 ? '0' + d : d;
var h = parseInt(times/ 60 / 60 % 24); //计算小时
h = h < 10 ? '0' + h : h;
var m = parseInt(times/ 60 / 60 / 24); //计算分数
m = m < 10 ? '0' + m : m;
var s = parseInt(times/ 60 % 60); //计算当前秒数
s = s < 10 ? '0' + s : s;
return d + '天' + h + '时' + m +'分' + s + '秒';
}
console.log(countDown('2023-4-11 18:00:00'));
var date = new Date();
console.log(date);
Array对象
1、检测是否为数组,返回true或者false
//检测是否为数组
//1、instanceof 运算符
var arr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);
console.log(obj instanceof Object); //特别地,也可以判断其他的
//2、Array.isArray(参数); H5新增 ie9以上
console.log(Array.isArray(arr));
console.log(Array.isArray(obj));
2、数组增删
//数组增删
//1、push()在数组末尾追加新的元素
var arr1 = [1, 2, 3];
arr1.push(4, 'ssy1'); //直接写参数
console.log(arr1);
console.log(arr1.push(5, 'ssy2')); //返回的是新数组长度,原数组也会变化
console.log(arr1);
//2、unshift()在数组前边添加新的元素
var arr2 = [7, 8, 9];
arr2.unshift(6, 'ssy2'); //直接写参数
console.log(arr2);
console.log(arr2.unshift(5, 'ssy1')); //返回的是新数组长度,原数组也会变化
console.log(arr2);
//3、pop() 删除数组最后一个元素
arr1.pop();
console.log(arr1);
console.log(arr1.pop()); //返回的是删除的元素,原数组也会变化
console.log(arr1);
//4、shift() 数组长度减1,再删除第一个元素
arr2.pop();
console.log(arr2);
console.log(arr2.pop()); //返回的是删除的元素,原数组也会变化
console.log(arr2);
3、数组排序
翻转和排序(reverse和sort函数)
//数组排序
//1、翻转数组
var arr3 = ['ssy', 12, '12ed32'];
arr3.reverse();
console.log(arr3);
//2、数组排序(冒泡排序)
var arr4 = [12,2,1,32,12,0,66];
arr4.sort(function(a,b) { //如果直接用sort会导致按照位数从左到右排序
// retrun a - b; 升序的顺序
return b - a; //降序
});
console.log(arr4);
4、查找数组索引号
indexOf(数组元素, [起始位置]); //起始位置不写,默认从第一个元素开始
lastIndexOf(数组元素, [起始位置]);//起始位置不写,默认从最后一个元素开始
5、案例数组去重(面试)
//数组去重['x', 's', 'a', 's', 'g', 'a', 'h', 'm', 'd', 'l']
//1、目标:把旧数组中里面不重复的元素取出来放到新数组里,重复元素只保留一个,放到新数组里去重
//2、核心算法:遍历旧数组,拿旧数组元素去查新数组,如果该元素在新数组里没有出现过就添加,否则不添加
//3、利用 新数组.indexOf(数组元素) 如果返回是-1就说明新数组没有该元素
//封装一个 去重函数 unique
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;
}
console.log(['x', 's', 'a', 's', 'g', 'a', 'h', 'm', 'd', 'l']);
console.log(unique(['x', 's', 'a', 's', 'g', 'a', 'h', 'm', 'd', 'l']));
6、数组转化为字符串
//数组转化为字符串
//1、tostring() 转化
var arr5 = ['asad', 12, '呵呵', 'jj', 0, false];
console.log(arr5.toString()); //,逗号分隔
//2、join(分隔符) 转化
console.log(arr5.join('-')); //自定义分隔符分隔,默认逗号,
7、其他
字符串对象
1、基本包装类型
js中有三种基本包装类型:String、Number和Boolean
基本包装类型:把简单数据类型包装成复杂数据类型,就有了属性和方法
2、字符串不可变
尽量不要大量拼接字符串和重新赋值,占内存
3、查询字符串所有特定元素出现位置及次数(面试)
// 查找字符串'ascascasdsacsfea'中所有a出现的位置以及次数
// 核心算法:先查找第一个a出现的位置
// 然后,只要indexOf返回的结果不是-1,就继续往后查找
// 因为indexOf只能查找到第一个元素,所以后边的查找,一定是当前索引加1,从而继续查找
var str = 'ascascasdsacsfea';
var index = str.indexOf('a');
var num = 0;
while (index !== -1) {
num++;
addr = index + 1;
console.log('第' + num + '个的位置是:' + addr);
index = str.indexOf('a', index + 1);
}
console.log('a出现的次数是:' + num);
4、根据位置返回字符
方法charCodeAt主要用于用户按了哪个键
查询字符串所有字符出现次数最多的字符
// 查找字符串'ascascasdsacsfea'中出现次数最多de字符,并统计次数
// 核心算法:利用charAt() 遍历这个字符串
// 然后把每个字符都存储给对象,如果对象没有该属性就为1,有就加1;
// 用for in 遍历对象,得到最大值和该字符
var str = 'ascascasdsacsfea';
var obj = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i); //chars 是字符串中每一个字符,有引号
if (obj[chars]) { //obj[chars] 得到的是属性值
obj[chars]++;
} else {
obj[chars] = 1;
}
}
// console.log(obj);
//遍历对象
var max = 0;
for (var k in obj) {
if (obj[k] > max) {
max = obj[k];
ch = k;
}
}
console.log('最多的字符是:' + ch + ' 次数:' + max); //a 5
5、字符串拼接和截取
6、字符串替换和转化为数组
//1、替换字符replace('被替换的字符', '替换为的字符') 他只会替换第一个
var str1 = 'adadffwf';
console.log(str1.replace('a', 'o'));
//替换所有d
while (str1.indexOf('d') !== -1) {
str1 = str1.replace('d', 's');
}
console.log(str1);
//2、字符串转化为数组 split('分隔符'); join('分隔符')把数组转化为字符串
var str2 = 'res,pink,blue,green'
console.log(str2.split(','));
7、转化大小写
toUpperCase() //转化为大写
tolowerCase() //转为小写
简单数据类型和复杂数据类型
!注意,简单数据类型null 返回的是一个空的对象 object;可以当做我们想要存储为空对象的变量。