1. 三种输出方式
// 单行注释
/*
shift+alt+a
*/
// 三种输出
console.log("在控制台打印"); //弱类型语言,可不加分号
alert("弹窗");
document.write("在网页显示");
// 可解析标签类型字符串
document.write("<h1>巴巴</h1>");
2. 声明变量
//1. 常量(字面量) 一些不可改变的数据
//变量 记录一些可变化的数据
//3. 变量声明规则 1.数字 字母 下划线 $组合,不能数字开头,不能汉字
// 2. 不能使用关键字
// 3. 不超过255字符
// 4. 可使用小驼峰方式 见名知义
// 5. var my_name = "张三";双引号 单引号 反撇号
var _123a = 2;
var my_name = "张三";
var myName = "张三";
var myAge = 12, mytel = 110;
//变量状态:声明变量 给变量赋值 使用变量
var let const
var
// 1.声明的变量不具备块级作用域的特性,它在{}外依然能被访问到;
// 3.循环中,使用了var关键字,它声明的变量是全局的,包括循环体内与循环体外。
// 4.声明的全局作用域变量属于 window 对象
// 5.使用 var 关键字声明的变量在任何地方都可以修改
// 6.变量提升时,变量可以先使用再声明
let
// 1.声明的变量只在let命令所在的代码块{}内有效,在{}之外不能访问;
// 3.Internet Explorer 11 及更早版本的浏览器不支持 let关键字;
// 4.循环中,使用let关键字,它声明的变量作用域只在循环体内,循环体外的变量不受影响。
// 5.声明的全局作用域变量不属于 window 对象
// 6.在相同的作用域或块级作用域中,不能使用 let 关键字来重置 var 关键字声明的变量 ,不能使用 let 关键字来重置 let 关键字声明的变量 ,不能使用 var 关键字来重置 let 关键字声明的变量,let 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
const
// const 用于声明一个或多个常量,声明时必须进行初始化,且初始化后值不可再修改,块级作用域,需要先声明再使用
3. 数据类型
//1. 基本数据类型:
// String字符串
// Number数值类型(整数 小数 负数)
// Boolean(true false)
// Undifind未定义(没赋值) null是一个表示"无"的对象,转为数值时为0;
// Null(赋了空值) undefined是一个表示"无"的原始值,转为数值时为NaN
//2. 引用数据类型:
// 除了剧本数据类型 都是引用数据类型
// 比如 (对象 数组 日期)对象类型 函数
var name = "悟空"; //String
var age = 2000; //number
var isGirl = false; //Boolean
//3. 对象
var obj_wukong = {
name:"孙悟空",
age:"2000",
address:"花果山",
brother:{
name:"猪八戒",
age:3000,
address:"高老庄",
wife:{
name:"高翠兰",
address:"高老庄"
}
}
}
//4. 数组和对象相互嵌套
var citys = [
{
name:"郑州",
areaList:["经开区","高新区","金水区"]
},
{
name:"周口",
areaList:["川汇区","淮阳区"]
}
];
console.log(citys);
4. 数据类型检测
函数引用数据类型检测用console.log(arr instanceof Array);
sonsole.log(arr.constructor)
包括Array Function Object Math Date
基本数据类型检测用console.log(typeof arr);
包括String Number Boolean Undefinde Null
5. 数据类型转换
其他类型变Number Number() parseInt() parseFloat() 2+ +2 2- -2
-
(Number类型,用于编写程序逻辑运算)
string转number:
1.数字字符直接转
2.空字符以及纯空格字符转为0
3.其他字符NaN
4.NaN不能进行运算,如果运算结果要么NaN要么false,NaN与任何数都不相等,与自身也不相等
var res = Number(‘0’);//0
var res = Number(’’);//0
5.parseInt()将其他类型转为数值型的整数,除字符串外其他都是NaN
( parseInt()的转换规则:
1.忽略字符串前面的空格,直到找到第一个非空格字符
2.如果第一个字符不是数字或者是负号,返回NaN
3.空字符串,返回NaN
4.如果第一个字符是数字,会继续解析第二个字符,直到解析完所有后续字符或遇到了一个非数字字符。
5.如果字符串以0x开头且后面跟数字字符,就会将其转为10进制数,同样,八进制也一样。
)
var res = parseInt(’’);//NaN
var res = parseInt(‘0’);//0
var res = parseInt([]);//NaN
var res = parseInt([ ,012]);//NaN
var res = parseInt([‘9’]);//9
var res = parseInt({});//NaN
var res = parseInt(’ 012fg’);//12
var res = parseInt(‘0x222222’);//2236962
6.parseFloat()也是从第一个字符开始解析每个字符,而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。规则如下:
(1.第一个小数点是有效的,第二个小数点无效
2.始终忽略前面的0,不分进制数
3.十六进制会被转换成0
4.空字符串转换为NaN)boolean转number:
true 1 false 0数组转number:
由于没有对应的API,先转字符串(默认触发toString()),再转number
var res = Number([]);//0
var res = Number([1,2]);//NaN对象转number:
也是先转字符串’[Object,Object]’
var res = Number({});//NaN
var res = Number({name:“li”});//NaN总结:
数组和对象直接运算,先转字符串,再转其他类型,最后再运算
基本类型间的转换只转一次,引用类型转基本类型先变字符串再变其他
其他类型变String String() +’’ ‘’+
-
(String类型,用于展示,建立与数组联系)
console.log(String([]));//'' console.log(String([1,2]));//'1,2' console.log(String({a:1,b:2}));//[Object,Object] console.log(String(undefined));//'undefined' console.log(String(null));//'null' console.log(String([123]+{}));//'null'
其他类型变Boolean Boolean() 除了下边这写是true其余都是false ==比较运算符个别关系运算符时
-
(BOOlean类型,用于条件句,或循环语句)
console.log(Boolean(false));//false console.log(Boolean(0));//false console.log(Boolean(''));//false console.log(Boolean(undefined));//false console.log(Boolean(null));//false console.log(Boolean(NaN));//false console.log(Boolean([]));//true console.log(Boolean({}));//true
-
null类型,用于 清理内存
-
undefined类型,表示某个变量已声明但未赋值用以判断函数是否有结果
-
array
-
function
6. 数据类型验证
var a =1;
// 验证是否是number
console.log(typeof(a) ==='number');
console.log(a instanceof Number);
console.log(a.constructor===Number);
// 验证是否是NaN
console.log(isNaN(a));
// 验证是否是undefined
console.log(typeof(a) ==='undefined');
console.log(a===undefined);
// 验证是否是null
console.log(!a && !isNaN(a) && typeof(a) != 'undefined' && a != 0)
//判断思路:所有数据转化false只有undefined null 0 NaN false
//如果一个数据不是undefined 0 NaN false ,那么根据排除法 返回true就是null 返回false就是上面其中一个
7. 运算符
//1. 算术运算符 + - * %
//2. 比较运算符(关系运算符)> < >= <= ==
var str1 = "z张";
var res = str1 + 123; //这里加是字符串拼接的意思
console.log(res);
console.log(str1 + res);
//3. 逻辑运算符 ||或 &&且 !非
// && 叫逻辑与,在其操作数中找到第一个虚值表达式并返回它,如果没有找到任何虚值表达式,则返回最后一个真值表达式。它采用短路来防止不必要的工作。
// || 叫逻辑或,在其操作数中找到第一个真值表达式并返回它。这也使用了短路来防止不必要的工作。在支持 ES6 默认函数参数之前,它用于初始化函数中的默认参数值。
// ! 运算符可以将右侧的值强制转换为布尔值,这也是将值转换为布尔值的一种简单方法。
var ab = false;
var ac = false;
console.log(ab || ac);
//4. 赋值运算符 =
//5. 判断数据类型的运算符
var a = null;
console.log(typeof a); //object
//NaN 的数据类型是数值
// 数组的数据类型是对象
// 日期的数据类型是对象
// null 的数据类型是对象
// 未定义变量的数据类型是 undefined
// 尚未赋值的变量的数据类型也是 undefined
//6. constructor 属性返回所有 JavaScript 变量的构造器函数。
"Bill".constructor
//返回"function String(){[native code]}"
8. 渲染页面
var arr = singers.data.artistList;
var htmlStr = "<div class='boxall'>";
for(var i=0; i<arr.length; i++){
htmlStr += "<div class='box'><img src="+arr[i].pic+"><br> <b>"+arr[i].name+"</b><p>"+arr[i].artistFans +"</p></div>";
}
htmlStr += "</div>";
document.write(htmlStr);
//var a = ```'a'''""`;
//不能嵌套相同的引号,只有``能换行能添加变量
var b = `sgdg${arr[i].name}gshghg`;//必须用``
var b = "fds"+arr[i].name+"sgfdgs";//里外引号要一样
var c = `dsds`+arr[i].name+`ffhhh`;//里外引号要一样
9. js内置对象
Math
Date
时间戳
// Math内置API
alert(Math.random());//0-1随机数不包括1
console.log(Math.random()*5);//0-5随机数不包括5
console.log(Math.ceil(1.5));//向上取证
console.log(Math.floor(1.5));//向下取整
console.log(Math.round(3.33));//四舍五入 结果3
console.log(Math.ceil(Math.random()*5));
console.log(Math.floor(Math.random()*8+4));
// console.log(Math.random*(b-a+1)+a);
console.log(Math.PI);
console.log(5*5*Math.PI.toFixed(3));//保留三位小数,如果不穿参数四舍五入
console.log(12.58.toFixed());
console.log(Math.pow(2,10));//2的10次方
console.log(Math.pow(2));//NAN not a number
console.log(Math.sqrt(9));//对9开平方根 结果3
console.log(Math.abs(-3));//绝对值
console.log(Math.max(1,2,3,4,5,6));//最大值
arr=[6,7,8];
console.log(Math.max(...arr));//...拓展arr数组,不能直接放arr数组
console.log(Math.min(...arr));
// data日期对象API
var date = new Date();//日期构造函数
console.log(date);
var year = date.getFullYear();//年
var month = date.getMonth();//月 返回0-11 比月份实际小1
var day = date.getDate();//日
var week = date.getDay();//星期几 周日0 1-6
console.log(year +"-" + month + "-" + day + "-" + week);
var hour = date.getHours();//时
hour = hour<10 ? "0" + hour : hour;
var minutes = date.getMinutes();//分
minutes = minutes<10 ? "0" + minutes : minutes;
var seconds = date.getSeconds();//秒
seconds = seconds<10 ? "0" + seconds : seconds;
console.log(hour+ ":" + minutes + ":" + seconds );
var milliseconds = date.getMilliseconds();//毫秒
// 设置日期对象
var date = new Date();
date.setFullYear(2000,1,1);//设置年 2000年1月1日
date.setMonth(1,6); //设置月 1月6日
date.setDate(22);
date.setHours(3);
date.setMinutes(3);
date.setSeconds(3);
date.setMilliseconds(999);
console.log(date);
//传入字符串 如果不写时分秒 默认08:00:00
console.log(new Date('2021-02-02 12:00:00'))
;
//除了2021-02-02 其他的如果不写时分秒 默认00:00:00
console.log(new Date('2021 02 02 12:00:00'));
console.log(new Date('2021,02,02 12:00:00'));
console.log(new Date('2021*02*02 12:00:00'));
console.log(new Date('2021.02.02 12:00:00'));
console.log(new Date('2021/02/02 12:00:00'));
// 时间戳
// 计算机元年1970年1月1日
function Timer(){
var date = new Date();
console.log(Date.now());//当前时间距1970年1.1毫秒数
var date1 = new Date('2023.2.21');
console.log(date1,date1.getTime(), date1.valueOf());//2023年距1970年毫秒数
var time = date1.getTime() - date.valueOf();//2023年2.21距当前毫秒数
var d = parseInt(time/1000/60/60/24);
var h = parseInt(time/1000/60/60%24);
var m = parseInt(time/1000/60%60);
var s = parseInt(time/1000%60);
setTimeout(Timer,1000);
document.getElementById('timer').innerHTML=('2023.2.21距当前时间' + d + '天' + h + '小时' + m + '分钟' + s + '秒');
};
Timer();
// 将时间戳转为标准时间
var chuo = new Date(555555555);
console.log(chuo);
</script>
10. 数组
//10.slice(start,end)截取 (开始索引,结束索引不包括) 返回截取下来的数组 对原数组无影响
//只写一个值的话就从这个数字截取到最后
// var res9 = arr7.slice(0,3);//134
// console.log(res9,arr7);
//splice(start,count,newItem) 删除数组中某些项 返回删除的数 改变原数组
//(开始值,要删几个 非必填 不填则删除后面所有 填0则不删 , 从开始删除的位置添加新的项)
// arr7=[7,8,7,8]
// var res10 = arr7.splice(1,2,6);
// var res10 = arr7.splice(1,2);
// var res10 = arr7.splice(1);
// var res10 = arr7.splice(1,2,6,7,7,8);
// console.log(res10,arr7);
// .filter()
//过滤数组
//参数:函数
//回参1:表示数组的元素
//回参2:数组索引
//return 过滤条件
//返回值:返回满足条件所有元素的新数组
//var res = arr.filter(function (item){
// return item.age>13;
// })
// console.log(res);
//.forEach() 遍历数组
// var arr = [
// {age:12},
// {age:13},
// {age:15},
// {age:123},
// ]
// arr.forEach(function(item,index) {
// console.log(item,index);
// });
// js内置处理数组方法
// 1.合并数组concat 有返回值 返回一个新数组 对原数组没有影响
// var arr1=[1,2];
// var arr2 = [3,4];
// var res = arr1.concat(arr2);
// console.log(res);
// 5.shift删除数组中的第一个 返回删除的项 改变原数组
// var res4 = arr3.shift();
// console.log(res4);
// 4.unshift 向数组头部添加 返回添加后的长度 改变原数组
// var arr3 = [1,2,3];
// var res3 = arr3.unshift(1,1);
// console.log(res3);
// 3.pop删除数组中最后一个 有返回值 返回删除的项 改变原数组
// var res2 = arr3.pop();
// console.log(res2);
// 2.push 向数组尾部添加项 有返回值 返回添加项之后的长度 改变原数组 同时向添加多项 用逗号隔开即可
// var res1 = arr3.push(5,6);
// console.log(res1);
//练习1. 将两数组合并 并将合并后的数组首尾交换
// var arr4 = [1,2,3,4];
// var arr5 = [5,6,7,8];
// var res = arr4.concat(arr5);
// console.log(res);
// var one = res.shift();
// var last = res.pop();
// res.push(one);
// res.unshift(last);
// console.log(res);
// 6.toString(); 将数组转换为字符串 不改变原数组
// var arr6 = [1,2,3,4,5,6];
// var res5 = arr6.toString();
// console.log(res5,arr6);/
// 7.join()将数组转为字符串 不添加值默认逗号隔开 添加值则由添加的值隔开 原数组不变
// var res6 = arr6.join(6);
// console.log(res6 , arr6);
// 8.reverse 翻转数组 改变原数组值
// console.log(arr6.reverse(),arr6 );
// 9.indexOf() 获取收个指定元素在数组中的位置的索引,若不存在返回-1
// var arr7 = [1,3,4];
// var res7 = arr7.indexOf(4);//2
// console.log(res7);
// lastIndexOf()从后往前
// var res8 = arr7.lastIndexOf(1);//0
// console.log(res8);
//练习2.不带7
// arr7 = [];
// for(var i=1 ;i<=100 ;i++){
// if(i%7==0 || i%10==7 || i-(i%10)/10==7 ){
// continue;
// }
// arr7.push(i);
// }
//delete 删除某个 可以删除 但位置会保留 数组长度不会变
// delete arr7[0];
// console.log(arr7);
//练习3.数组去重
//法一双重for循环判断(从后边删除的)
// var arr11 = [1,2,412,4,51,312,4551,2,31,51,1,88];
// for (let i = 0; i < arr11.length; i++) {
// for (let j = i+1; j < arr11.length; j++) {
// if(arr11[j]=arr11[i]){
// arr11.splice(j,1);
// j--;//arr11.length变化
// }
// }
// }
// console.log(arr11);
//法二根据indexOf返回值是否为-1判断
// var arr11 = [1,2,412,4,51,312,4551,2,31,51,1,88];
// var newArr11=[];
// for(var i=0 ;i<arr11.length ; i++){
// var res11 = newArr11.indexOf(arr11[i])
// if(res11 == -1){
// newArr11[newArr11.length]=arr11[i]
// continue;
// }
// }
// console.log(newArr11);
//法三前后索引对比(从前边删除的)
// var arr11 = [1,2,2,3 ];
// for (let i = 0; i < arr11.length; i++) {
// if(arr11.indexOf(arr11[i]) != arr11.lastIndexOf(arr11[i])){
// arr11.splice(i,1);
// }
// }
// console.log(arr11);
//法四indexOf索引与下标对比
// var arr11 = [1,2,2,3 ];
// for (let i = 0; i < arr11.length; i++) {
// if(arr11.indexOf(arr11[i]) != i){
// arr11.splice(i,1);
// i--;
// }
// }
// console.log(arr11);
11. 字符串
//split();将字符串分割为数组 返回分割后的数组 不会改变原来的数组
console.log(str2.split("人"), str2);//以"人"分割
console.log(str2.split(), str2);
//slice(start,end);截取 不包括end 返回截取的字符串 不影响原字符串 第一个数如果为负数,从后往前查
console.log(str2.slice(0, 2), str2);
console.log(str2.slice(2), str2);
console.log(str2.slice(-4), str2);
//substr(from,count) 截取 (从哪里开始 , 截取几个) 返回截取下来的字符串 不影响原字符串
console.log(str2.substr(2, 3), str2);
// sort排序 会改变原数组 有返回值 返回拍好的数组 默认从小到大升序
// var res=arr.sort();//把数组里面的元素当成了字符串 按unicode码 ascii码 英文字符 数字 英文小写 汉字 中文字符
// console.log(res);
//遍历对象
// var obj={
// a:1,
// b:2,
// c:[1,2,3]
// }
// console.log(obj.length);//对象没有长度 无法用for遍历 使用for...in
// for(var key in obj){
// // console.log(key);//key
// console.log(obj[key]);//值
// //console.log(obj.key);//undefinde
// }
//substring(start,end) 截取 不包括end 第一个参数如果为负数还是从0开始
//console.log(str2.substring(1,3));
//console.log(str2.substring(-1000));
//获取对象中所有键 返回一个由键组成的数组
// var keys=Object.keys(obj);
// console.log(keys);
//获取值
// var values = Object.values(obj);
// console.log(values);
// 判断obj1中是否存在eat这个属性
// var obj1 =
// {
// name:"明",
// eye:2,
// hair:"black"
// }
// flag=false;//假设不存在
// for(var key in obj1){
// //var keys=Object.keys(obj1);//key数组
// // for (let i = 0; i < keys.length; i++) {
// if(key=="eat"){
// flag=true;
// break;
// // console.log("yes");
// }
// }
// // }
// if (!flag) {
// console.log("不存在");
// }
// else{
// console.log("cunzai");
// }
// Object.keys(ogj1).indexOf('eat') == -1 ? alert("不存在") : alert("存在");
//字符串
// for循环遍历字符串
var str = '123456789';
for (let i = 0; i < str.length; i++) {
console.log(str[i]);
}
//字符串拼接
var str1 = "1"; var str2 = "2"; var str3 = "3";
console.log(str1 + str2 + str3);
//concat 拼接 连接 字符串
var res1 = "你好".concat(str1, str2, str3);
console.log(res1);
//indexOf和lastIndexOf 跟数组中的用法是一致的
var str1 = "撒娇女人最好命";
console.log(str1.indexOf("女女"));//-1
console.log(str1.lastIndexOf("撒娇"));//2
//replace()替代 替换 有返回值 返回替换后的字符串 替换多个相同的字符的话 智能替换第一个 不改变原来的字符串
var str2 = "男人得有钱";
console.log(str2.replace("有钱", "^^"), str2);//只替换一个$,别的符号例外 且只能替换第一个匹配的"有钱""
//replaceAll()存在兼容问题
console.log(str2.replaceAll("钱", "//"), str2);//只替换一个$,别的符号例外
//建议用for循环一个个替换 , 或使用正则表达式替换
// i不区分大小写 g全局匹配 m多行匹配
console.log(str2.replace(/钱/g, "$"), str2);
//加密电话
var num = "15188470181";
var num1 = num.replace(num.substr(3, 4), "****");
console.log(num1, num);
//大小写转换 原字符串不变
var str4 = "sdggfgg";
console.log(str4.toUpperCase(), str4);//变大写
var str5 = "HJUYHIUIUIU";
console.log(str5.toLowerCase(), str5);//变小写
//互相转换
var str6 = "JAVAsCRIPT";
var res = "";
for (let i = 0; i < str6.length; i++) {
var code = str6[i];
if (code == str6[i].toLowerCase()) {
res += code.toUpperCase();
} else {
res += code.toLowerCase();
}
}
console.log(res);
//trim(); 去除字符串两边空白符 不影响原字符
var str7 = " 今天周三 ";
console.log(str7.trim());//去掉两边空格
console.log(str7.trimLeft());//去掉左边空格
console.log(str7.trimRight());//去掉右边空格
//es6 includes(); 搜索字符是否存在 true存在 false不存在
console.log(str7.includes("周三"));//false
//charAt(index) 通过索引值 找到指定位置的字符
console.log(str7.charAt(3));//周
//starsWith() 和 endsWith()判断字符串是否是以某个字符开头和结尾的 返回值true false
console.log(str7.startsWith("周"), str7.endsWith("三"));//false
//isNaN判断是不是数字 数字:false 不是数字:true
//NaN:not a number 属于number类型
//NaN不等于任何值,包括他本身
console.log(typeof ("1"));
console.log(typeof ("g"));
console.log(isNaN("1"));//false 1是个数字
console.log(isNaN("g"));//true g不是个数字
//练习 长度11,开头1,全是数字,不符合则提示输入有误,正确则把手机号中间四位换成****
var tel = prompt("请输入电话号码");
if (isNaN(tel)) {//true不是数字
alert("请输入数字");
} else {//false是数字
if (tel.charAt(0) == 1) {//true是1开头 charAt和startsWith能判断字符串,但不能判断数字
if (tel.length == 11) {
var tel1 = tel.replace(tel.slice(3, 7), "****");
alert(tel1);
} else {
alert("长度不是11");
}
} else {
alert("数字开头不是1");
}
}
12. Object对象
// 声明对象
var obj={
name:"老王"
}
var obj3= new Object(8);
console.log(obj3);
// 取属性值
console.log(obj.name) ;
console.log(obj["name"]) ;
// 添加属性值
obj.age="1";
obj["hair"]="black";
// 删除属性
delete obj.hair;
// console.log(obj);
// 更改属性值
obj.age=18;
//对象有可扩展性 默认扩展性为true
//检查是否有扩展性的方法: Object.isExtensible(obj);
Object.isExtensible(obj);
//阻止拓展 禁止给对象添加新属性 但可以修改和删除属性 Object.preventExtensions()
Object.preventExtensions(obj);
//冻结 Object.freeze() 无法添加修改删除
Object.freeze(obj);
13. 函数
函数的定义
// 函数:也叫做方法,它的作用主要就是用来封装重复的代码,来达到代码复用的效果
function func1 () {
alert('我是func1')
}
func1();
// 匿名函数/函数表达式 通过一个变量来接收函数
var fn2 = function () {
alert('我是fn2');
};
console.log(fn2); //此时fn2是一个函数表达式
fn2();
函数的参数
// 函数中的参数:实参和形参,实际参数、形式参数
// 形式参数:在定义函数时,写在括号中的自己定义,每个形参之间用逗号隔开
function add (a, b) {
// 在函数中就要使用这两个形式参数;
return a + b;
}
// 实际参数:在调用函数时,写在括号中的参数;
console.log(add(1, 2));
console.log(add(123, 4124));
作用域
变量状态:声明变量 给变量赋值 使用变量
判断使用的是那一个变量:在当前作用域中查找,是否声明,如果声明,找最近一次的赋值
// 作用域:全局作用域和局部作用域
// 全局作用域:范围指的整个script代码块中
var a = 1;
// 局部作用域/函数作用域:声明在函数内部的变量,只能在函数中使用,函数内的变量在函数执行时才声明
function f1 () {
var b = 2;
console.log(a);
console.log(b);
}
f1();
//console.log(b); //Uncaught ReferenceError: b is not defined
function f2 (params) {
var a = 10;
// 当访问一个变量时,会优先在自己的作用域中寻找,如果没有,就往上找;
console.log(a);
}
f2();
console.log(a);
// 全局作用域(整个script标签或一个单独的js文件 或 函数内部没有声明直接定义的变量)
// 局部作用域/函数作用域(函数内部的名字只在函数内部起作用 函数形参也是局部变量 function max (a,b)这种函数默认是全局变量)
// console.log(qqq);//访问不了
// function jisuan(){
// console.log(ppp);
// }
// var qqq = 1;
// console.log(ppp);//访问不了
// 变量会提升声明但不提升值,函数如果是变量形式也会同样提升,函数如果是函数命名形式会将内容一并提升
变量提升
// 变量提升
var a;
console.log(a); // undefined
var a = 100;
// 函数提升
f1();
function f1 (params) {
alert('我是f1')
}
// add(3,4);//变量命名的函数前面不能调用,函数不提前 匿名形式的提前能调用
//函数表达式(匿名函数) add是变量不是函数名
// function add(a,b){//形参可看做不用声明的变量
// console.log(a+b);
// }
// add(1,2,3);//实参多于形参的不参与计算
// add(2);//2+undifind 结果是NaN
arguments
argumnets对象,接收所有传入的实参,是一个类数组,可以通过索引去获取到传入的参数,只能在函数体内使用 与数组的区别是没有数组的一些方法如pop
function f1 (a, b, c) {
console.log(a, b, c);
// argumnets对象,接收所有传入的实参,是一个类数组,可以通过索引去获取到传入的参数,只能在函数体内使用
console.log(arguments, arguments[3]);
// instanceof 用来判断引用类型Function Object Array
console.log(arguments instanceof Math);
var arr = [1, 2, 3];
console.log(arr instanceof Array);
}
f1(1, 2, 3, 4, 5, 6, 7, 8);
f1(1);
// 形式参数的作用主要就是为了接受调用函数时,传入的实际参数
/*
当实际参数的个数<形式参数时,从左开始接受,多余的显示为undefined
当实际参数的个数>形式参数时,那么形式参数就按照实际参数从左到右的顺序接收,多余的则不再接收
*/
回调函数
将一个函数当成另一个函数的实参,这个作为参数的函数就叫做回调函数,callback;
// sayName为回调函数
function sayName (name) {
alert('Hi,' + name);
}
function f1 (func, value) {
console.log(func);
func(value);
}
f1(sayName, 'Jack');
sayName('jack');
函数构造对象
//函数构造对象
// function Star(uname,uage){
// this.name = uname;
// this.age = uage
// }
// var ldh = new Star("刘德华",18);
// console.log(ldh.age);
定时器和延时器
setInterval(callback,time);
定时器:每隔多少秒,执行一次callback中的代码; 一直执行
setTimeout(callback, timeout);
延时器:设置一个时间delay,推迟多少秒执行这个代码; 只执行一次,写在函数里面也可实现setInterval的效果
//3、每秒页面上输出一次:距离2022年3月1日还有xx小时xx分钟xx秒,小时可以超过24,分钟不能超过60,秒不能超过60;
//法一 setInterval(function(){},1000);
var h;
var m;
var s;
var aaa='2022/3/1';
setInterval(function(){
var now = new Date();
var future = new Date(aaa);
var nowSecond = Date.now();//当前时间戳
var futureSecond = future.getTime(future);//2022.3.1时间戳
var timeDeffierence = futureSecond - nowSecond//时间戳差值
h =parseInt(timeDeffierence/1000/60/60) ;//时
m =parseInt(timeDeffierence/1000/60%60) ;//分
s =parseInt(timeDeffierence/1000%60) ;//秒
num.innerText = `距离2022年3月1日还有${h}小时${m}分钟${s}秒`;
},1000);
//法二 setInterval("time('2022/3/1')",1000);
var h;
var m;
var s;
setInterval("time('2022/3/1')",1000); //回调函数有参数时需要用引号包括 没有参数时直接setTimeout(Timer,1000);
function time(aaa){
var now = new Date();
var future = new Date(aaa);
var nowSecond = Date.now();//当前时间戳
var futureSecond = future.getTime(future);//2022.3.1时间戳
var timeDeffierence = futureSecond - nowSecond//时间戳差值
h =parseInt(timeDeffierence/1000/60/60) ;//时
m =parseInt(timeDeffierence/1000/60%60) ;//分
s =parseInt(timeDeffierence/1000%60) ;//秒
num.innerText = `距离2022年3月1日还有${h}小时${m}分钟${s}秒`;
}
//法三 setTimeout("time('2022/3/1')",1000);
var h;
var m;
var s;
function time(aaa){
var now = new Date();
var future = new Date(aaa);
var nowSecond = Date.now();//当前时间戳
var futureSecond = future.getTime(future);//2022.3.1时间戳
var timeDeffierence = futureSecond - nowSecond//时间戳差值
h =parseInt(timeDeffierence/1000/60/60) ;//时
m =parseInt(timeDeffierence/1000/60%60) ;//分
s =parseInt(timeDeffierence/1000%60) ;//秒
num.innerText = `距离2022年3月1日还有${h}小时${m}分钟${s}秒`;
setTimeout("time('2022/3/1')",1000);
}
time('2022/3/1');
14. 深拷贝 浅拷贝
//深拷贝 复制一个变量 当改变一个变量时 对另一个的变量没有影响
var a=1;
var b=a;//a或b改变 另一个不改变
a=3;
b=4;
console.log(a,b);
//浅拷贝 复制一个引用类型的变量 当改变一个变量中的属性时 另一个变量也会跟着变化
var obj={
name:"王"
};
var obj1=obj;//改变obj或obj1 另一个也改变
obj.age=20;
//若果想要实现引用类型的深拷贝 就可以使用遍历把一个对象或数组中每一个值复制到另一个变量中
var obj2={};
for(var key in obj){
obj2[key] = obj[key];
}
obj.age = 30;
obj2.name = "李";
//基本数据类型变量和值都存在栈中,
//引用数据类型变量和值的指针存在栈中,真正的值存在堆中 指针指向堆中值的地址
15. unll undefined区别
undefined在内存中占据了空间,没有赋值
null没有占据空间
优化内存,吧不使用的变量使用null清空
16. 有var变量和没var变量的区别
var声明的变量可以在当前作用域中任意位置都能使用,其作用是将变量提升到当前作用域顶端
没用声明的变量需要先有再使用
17. not defind和undefined
not defined 报错原因没有发现变量
eg: console.log(a); a=2;
undefined 有var变量但没有值
eg:console.log(a);var a=2;
18. ahdkjfhhgfkhjjghkfjd查重复的个数
19. 数据结构
- 栈
- 队列
- 集合
- 链表
- 字典
- 树
- 图
- 堆
栈
队列
// 队列 模拟等待执行的任务
var quen=[];
quen.push('任务一')
quen.push('任务二')
quen.push('任务三')
//先执行完毕的 先推出
quen.shift()
quen.shift()
quen.shift()
执行上下文
预编译
语言分析
预编译(针对函数执行)
-
- 创建go(global object)对象 也是 全局执行上下文
-
- 将全局中 var function 定义的变量和函数,作为go的属性,也叫做变量提升,函数声明提升
函数执行时
- 创建AO
- 形参提升
- 变量提升
- function函数提升
- 将实参赋值给形参(形参和实参相统一)
<script>
function foo(){
var a = 213
// ao:{
// arguments:{
// length:0
// }
// a:123
// b:function
// d:unfined
// }
function b (){}
var d = function(){}
// ao:{
// arguments:{
// length:0
// }
// a:123
// b:function
// d:function
// }
}
foo() // 执行完毕 AO销毁
/*
ao:{
arguments:{
length:0
}
a:undefined
b:function
d:unfined
}
*/
</script>
<script>
// 练习 编译过程
/*
// 未执行:准备阶段
GO{
a:undefined,
b:undefined,
foo:Function,
}
*/
var a = 123;
/* 执行
GO{
a:123,
b:undefined,
foo:Function,
}
*/
var b = 456;
/*
GO{
a:123,
b:456,
foo:Function,
}
*/
a = 234;
/*
GO{
a:234,
b:456,
foo:Function,
}
*/
function foo(a,b){
var c = 123;
/*
AO {
arguments:{
0:1,
1:20,
lenght:2
}
c:132
bar:function,
a:1,
b:20
}
*/
function bar(){}
b = 567
/*
AO {
arguments:{
0:1,
1:20,
lenght:2
}
c:132
bar:function,
a:1,
b:567
}
*/
}
foo(1,20)
/* 函数准备执行
AO {
arguments:{
0:1,
1:20,
lenght:2
}
c:undefined
bar:function,
a:1,
b:20
}
*/
</script>
解析执行
面试:预编译