函数的两种声明方式
1.利用函数关键字自定义函数;2.函数表达式(匿名函数);
function fn(){
}
fn();
2.var fun = function(){
}
fun();
这时候是有函数名和变量名的区别的。
fun是变量名,函数表达式跟声明变量差不多,但是变量里面存的是值而函数表达式里面存的是函数。
函数表达式也可以进行传递参数。
JS作用域
1.两种作用域:
就是代码名字在某个范围内起作用和效果
目的是为了提高程序的可用性减少命名冲突。
作用域:全局作用域,局部作用域;
全局作用域:整个script标签就是一个全局作用域或者是一个单独的外部js文件。
局部(函数)作用域:在函数内部就是局部作用域例如说我们写的智能选择模型,里面的函数。
变量:全局变量和局部变量,在函数内部也能使用全局变量。
全局变量的一种特殊情况:在函数内没有声明直接赋值的变量是全局变量。
2.作用域链
内部函数可以访问外部函数的变量。
链式查找就是一层一层的往上查找(就近原则);
内部函数在访问外部函数的时候就是采用链式查找的方式。
JS的预解析
报错的分析:
函数是可以在上面调用的,而变量是不能在代码执行语句的下面定义的。
js运行需要先预解析,再执行代码。
js引擎会把js的所有var和function提到当前作用域的最前面。
预解析分为变量预解析(变量提升)和函数预解析(函数提升)
函数提升只是把声明函数提升到前面而不会直接调用函数,所以调用函数的语句放在函数前面并不会报错。
注意变量提升真的就只是把定义变量提升了,并不提升赋值操作。直接举个例子:
console.log(fun);
var fun = 10;
//就是
var fun;
console.log(fun);
fun=10;
所以为什么运行的时候会报错一目了然。
还有就是再分析预解析的时候要注意将变量定义提前的时候会不会同时生成全局变量。
因为在函数中直接赋值的变量相当于全局变量。
对象
对象必须是一个具体事物,并不是一个泛指的-一组无序的相关属性和方法的集合。
对象是由属性(特征)和方法(行为)组成的。
对象能够保存的信息结构更清晰,在我们写的输出当前时间语句中能很清晰的观察到。
创建对象的三种方法:
1.利用字面量创建对象:
用{}放入信息,并用逗号隔开。
在调用对象的属性:
console.log(obj.uname);
//或者
console.log(obj['age']);
2.利用new Object创建对象
//在其中先创建一个空的对象再给对象赋值
var obj = new Object();
obj.uname='某某';
obj.sayHi=funcation(){
console.log();
}
//使用
console.log(obj.uname);
console.log(obj[uname]);
obj.sayHi();
3.利用构造函数创造对象
一次创建多个对象,利用函数的方法一次创建多个对象。
构造函数就是把我们对象里面一些相同的属性和方法封装到函数里面。
它总与new一起使用。
function 构造函数名(){
this.属性 =值;
this.方法=function(){}
}
new 构造函数名();
构造函数名首字母要大写,
也是形参实参,比较容易理解。
function 构造函数名(形参1,形参2...){
this.属性名=形参1;
this.属性名=形参2;
this.函数名= function(形参n){
console.log(形参n)
}
}
var 对象名= new 构造函数名(实参1,实参2...);
console.log(对象名.属性名);
对象名.函数名('实参');
差不多就是这样的。
很简单的理解。
变量是单独存在的,需要声明而属性是依托对象存在的再使用的时候是需要写对象名.属性名。
在对象里的方法调用也同理需要对象.方法
都需要一个.来表示某对象里的属性或方法。
创建对象的过程也可以称为对象的实例化。
for (var k in obj){
console.log(k); //输出属性名
console.log(obj[k]); //输出属性值
}
对象就是一组无序的相关属性和方法的合集。
for in这个方法来遍历我们的对象。
内置对象
自定义对象(自己创造的对象);内置对象;浏览器对象;
JS给我们提供的对象:
Math,Date,Array,String
可以在MDN里面更加详细的了解其中的属性和方法。
下面是一个小例子,上面我们写过不使用函数输出数组最大值的方法
下面将用户自己输入的数值通过函数的方式找到最大值。
var arr=[];
var n=prompt("请输入一共有多少个数");
for(var i=0;i<n;i++){
var j;
j=i+1;
arr[i]=prompt("请输入第"+j+"的数值");
}
function myMath(arr){
var max = arr[0];
for(var i=0;i<arr.length;i++){
if(max<arr[i]){
max=arr[i];
}
}
return max;
}
console.log(myMath(arr));
Math
的三个取整方法
console.log(Math.floor(1.1));//向下取整
console.log(Math.ceil(1.1));//向上取整
console.log(Math.round(1.1));//四舍五入
Math里面的随机数方法Math.random()
我们曾经制作随机歌曲的时候曾经用过这个方法。
var arr = ["走马", "撒野", "story", "粑粑", "静悄悄", "浪漫主义", "浪漫主义2.0"];
alert("正在播放:" + arr[parseInt(Math.random() * arr.length)]);
这个就是当时我们制作的随机选歌,这时候突然想到随机摇人了哈哈哈哈
显而易见这个是数组内所有的数都包含那么不完全包含的怎么实现呢?
这时候我们有了两个整数并且想要得到这两个数之间的随机整数,下面是代码
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1))+min;
}
//注意max-min+1是多少个数的意思,
//和前面的random联系在一起可以理解为比最小的数大多少,当然这里面是包含0的
仔细看看事实上很容易理解随机选择。
这是一个猜数字的小游戏,注意我们写了一个floor是为了使它变成一个整数。
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var n =getRandom(1, 10);
while (true) {
var i = prompt("请输入你猜测的数字");
if(i > n){
alert("大了");
} else if(i < n){
alert("小了");
} else{
alert("666,猜对了!");
break;
}
}
Date
是一个构造函数,必须使用new来调用创建我们的日期对象,/
var myDate = new Date();
var y = myDate.getFullYear();
var m = myDate.getMonth();
var d = myDate.getDate();
var h = myDate.getHours();
var mi = myDate.getMinutes();
var s = myDate.getSeconds();
m = m < 10 ? "0" + m : m;
h = h < 10 ? "0" + h : h;
mi = mi < 10 ? "0" + mi : mi;
s = s < 10 ? "0" + s : s;
alert(y + "-" + m + "-" + d + " " + h + ":" + mi + ":" + s);
//通过Date总的毫秒数(时间戳)
var date = new Date();
console.log(date.valueOf());//当前时间距离1970.1.1的总毫秒数
console.log(date.getTime());
//最常用的写法
var date1= +new Date();//+new Date() 返回的就是总的毫秒数
console.log(date1);
//H5 新增的 获得的总毫秒数
console.log(Date.now());
做一个倒计时的效果:
setInterval(countDown, 1000);
function countDown(time){
var nowTime = +new Date();//都是距离1970.1.1的总毫秒数
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);
m=m<10?'0'+m:m;
var s = parseInt(times % 60)
s=s<10?'0'+s:s;
return d + '天' + h + '时' + m + '分' + s +'秒';
}
console.log(countDown('2022-11-14 00:00:00'));
var date = new Date();
console.log(date);
注意不要写错字母,所以推荐使用vscode
数组判断
1.instanceof可以检验是否为数组:
console.log(数组名 instandceof Array);
输出true/false来判断是否为数组
2.Array.isArray(参数) ie9以上版本才支持
console.log(Array.isArray(数组名));
添加或删除数组元素
1.push()在数组末尾添加一个或者多个数组元素
数组名.push(数组元素,数组元素);
console.log(arr.push(数组元素));//会返回现在数组的长度.
2.unshift会在数组的开头添加一个或多个元素
数组名.unshift(数组元素);
console.log(数组名.unshift(数组元素));
3pop()删除数组的最后一个元素
//所以说是不是如果规定一个数组必须多少个数,如果多了可以利用循环删除呢?
数组名.pop();
console.log(数组名.pop());
4.shift()删除第一个元素
splice()数组删除(第几个开始,删除几个),返回值是返回被删除的新数组,并会影响原数组
同上...
筛选数组:
删掉比2000大的数:
这是通过将大于2000的数替换到数组中最后一个数的方法来达到效果
//这里我先自己尝试了一下
var arr = [1500,1200,2000,2100,1800];
for(var i=0;i<arr.length;i++){
if(arr[i] > 2000){
var temp;
temp=arr[arr.length-1];
arr[arr.length-1]=arr[i];
arr[i]=temp;
arr.pop();
}
}
console.log(arr);
//也可以达到删掉比2000大的数的效果
这是通过建立新数组将小于2000的数加入到新数组中的方法来达到效果:
//筛选数组.
var arr = [1500,1200,2000,2100,1800];
var newArr = [];
for(var i=0;i<arr.length;i++){
if(arr[i] < 2000){
newArr.push(arr[i]);
}
}
console.log(newArr);
但是上面的会导致数组内乱序。
数组排序:
//翻转数组:
var arr = ['pink','red','blue'];
arr.reverse();
//冒泡排序:
var arr = [3,4,7,1];
arr.sort();
//冒泡排序:
var arr = [3,4,7,1];
arr.sort(fountion(a,b){
return a-b; //按照升序排列
//return b-a; //按照降序排列
});
谁理解前面写完排序,现在竟然有sort();,r如果涉及到双位数请使用下面的冒泡排序。
数组索引:
//只返回第一个满足程序的索引号
arr.indexOf(元素名);
//如果找不到该元素会返回-1值
arr.lastIndexOf(元素名);
//会从后往前找索引号
数组去重:
//数组去重.self
var arr = [1,2,3,1,2,3,1,2,3,];
var newArr =[];
for(var i=0;i<arr.length;i++){
var n = newArr.indexOf(arr[i]);
if(n < 0){
newArr.push(arr[i]);
}
}
console.log(newArr);
上面自己做的例子,下面是学到的例子:
//封装一个去重的函数;
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([1,2,3,1,2,3,1,2,3,]);
console.log(demo);
将数组转换为字符串:
1.数组名.toString(),但是这种不太方便变成字符串会有逗号
2.join()里面可以放分隔符
括号里面如果放了分隔符里面就是分隔符,如果里面啥也没有那就是逗号。
数组名.join();
concat()连接两个或者多个数组
slice()截取:slice(begin,end)
基本包装类型:
就是把简单的数据类型转为复杂数据类型
String()
字符串还具有不可变性。
根据字符串查找返回的位置:
str.indexOf('要查找的字符',[起始的位置]);
下面我们先做一个查找一串字符串里面某一个数出现的位置和次数:
//输出某一字符的位置
var str="afafbssaf";
var index = str.indexOf('s');
var num = 0;
while(index != -1){
console.log(index);
num++;//次数
index = str.indexOf('s',index +1);
}
根据位置返回字符:
charAt(index);
charAt(第几个);
str.charAt()
简单记一下ascll表;
chatCodeAt(index);返回相应索引的的ascll值,
str[index]获取指定位置处字符和charAt等效,可以在H5上使用
统计出现最多次数的字符:
//统计出现次数最多的字符和次数:
//核心算法:charAt()
//把每一个字符都存给对象
var str = 'afgghsdfzcsdsdaf';
var dx = {};
for(var i = 0;i<str.length;i++){
var chars = str.charAt(i);
if(dx[chars]){
dx[chars]++;
}else{
dx[chars]=1;
}
}
console.log(dx);
//找到最大的对象
var max = 0;
//定义对象中的属性名
for(var k in dx){
if(dx[k] > max){
max=dx[k];
j=k;
}
}
console.log(max);
console.log(j);
替换字符串以及转换为数组
//替换字符
// 但是只会替换第一个字符
replace('被替换的字符','替换为的字符');
//while循环将所有的o全换为*
var str = 'asodfoaag';
while(str.indexOf('o') != -1){
str = str.replace('o','*');
}
console.log(str);
//字符转换为数组:
var str = 'af,ag,af,asf';
console.log(str.split(','));
转换大小写:
toUpperCase()//转换大写
toLowerCase()//转换小写