数组
JS两种创建数组的方式
利用new 创建数组
//使用new
let arr = new Array();//创建了一个空数组
arr = [1,2,3,4];
console.log(arr);
利用数组字面量创建数组js
//使用字面量(常用)
let arr2 = [];//创建了一个空数组
arr2 = [1,2,'warm',true];
console.log(arr2[2]);
遍历
//遍历
let arr3=['胡歌','沈腾','彭于晏']
console.log('我喜欢的明星有:');
for(let i=0 ; i<arr3.length ; i++){
console.log(arr3[i]);
}
函数
声明方式1:
function 函数名(形参列表){
函数体
return 返回值;
}
声明方式2:函数表达式(匿名函数)
函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而函数表达式里面存的是函数,函数表达式也可以进行传递参数。
let 变量名 = function(){
console.log('这是函数表达式,')
};
声明方式3
let f3 = (a, b) => { return a + b };
闭包函数
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
案例:查看你的生肖星座和你一共活了多少天
function Show(year, month, day) {
function Constellation() {
let constellation = ['摩羯座', '水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座',
'狮子座', '处女座', '天枰座', '天蝎座', '射手座', '摩羯座'
];
let time = [19, 18, 20, 19, 20, 21, 22, 22, 22, 23, 22, 21];
let uConstellation = (day <= time[month - 1]) ? (constellation[month - 1]) : (constellation[month]);
console.log(`您的星座是:${uConstellation}`);
}
function Showxz() {
let year2 = year % 12;
let shengXiao = ['猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊'];
if (year2 >= 0) {
console.log(`您的生肖是:${shengXiao[year2]}`);
}
}
function UDay() {
// let birthday = new Date(year, month - 1, day);//数字型 数字型date的月份是从0开始计算
let birthday = new Date(year + '/' + month + '/' + day); //字符串型
let today = new Date();
let time = parseInt((today.getTime() - birthday.getTime()) / (1000 * 3600 * 24));
console.log("从出生到今天活了" + time + "天 ");
}
return {
showConstellation: Constellation(),
showXz: Showxz(),
showDays: UDay()
}
}
let show = Show(2002, 1, 5);
show.showConstellation;
show.showXz;
show.showDays;
return
1.除了返回值以为还有终止函数的作用
function getSun(num1,num2){ return num1+num2; alert('这里面的代码不会被执行了') }
2.return只能返回一个值,如果没有return则返回undefined
break,continue,return的区别
break:结束当前循环体
continue:跳出本次循环,继续执行下次循环
return:不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前函数体内的代码。
arguments
当我们不确定有多少个参数传递的时候,可以用arguments来获取,在JavaScript中,arguments实际上它是当前函数的一个内资对象,所有函数的内置了一个arguments对象,arguments对象中存储了传递的所以实参。
function fn(){ conselo.log(arguments);//拟数组对象 } fn(1,2,3,4);
伪数组形式
arguments展示形式时一个伪数组形式,因此可以遍历,伪数组具有以下特点:
1.具有length属性
2.按索引方式存储
3.不具有数组的push,pop等方法
作用域
-
JavaScript作用域:就是代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性更重要的是减少命名冲突。
-
JS的作用域(es6)之前:全局作用域 局部作用域。
-
全局作用域: 整个script标签 或者是一个单独的js文件。
-
局部作用域(函数作用域) 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用。
全局变量
-
全局变量:在全局作用域下的变量,在全局下都可以使用
-
特殊情况下 在函数内不适应var声明的变量也是全局变量(不建议使用)
局部变量
-
在局部作用域下的变量,后者在函数内部的变量就是,局部变量
js中没有块级作业域,js的作用域:全局作用域,局部作用域,现阶段我们js没有块级作用域,
我们js也是在es6的时候新增的块级作用域
作用域链
-
只要是1代码,就至少有一个作用域
-
写在函数内部的局部作用域
-
如果函数中还要函数,那么在这个作用域中就又可以诞生一个作用域
-
内部函数可以访问外部函数变量这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链,一级以及往上找 就近原则。
<script>
//作用域链 :内部函数访问外部函数 一级以及往上找 就近原则
let num = 10;
function fn(){
let num = 20;
function fun(){//内部函数
console.log(num);
}
fun();//需要一层一层调用
}
fn();
</script>
预解析
js引擎运行Js分为两步:预解析 和 代码执行
-
预解析:js引擎会把js里面所有的var 还有function提升到当前作用域的最前面
-
执行代码:按照代码书写的顺序从上往下执行
预解析分为 变量预解析(变量提升)和函数预解析(函数提升)。
-
变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。
-
函数提升:把所有的函数声明提升到当前作用域的最前面。
<script>
//1. 变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。
//2. 函数提升:把所有的函数声明提升到当前作用域的最前面。
//这两行代码相当于---变量提升
//1. var num; --变量声明提升到当前的作用域最前面
//2. console.log(num);
//3. num = 10;
//相当于上面三行代码,这就是js中的预解析
console.log(num);//undefined
var num = 10;//let num的话前面会输出Cannot access 'num' before initialization
fn();//可以输出11 不会报错
function fn(){
console.log(11);
}
//上面代码相当于---函数提升
//function fn(){ ----函数声明提升到当前作用域的最前面
// console.log(11);
//}
//fn();
fun();//fun is not a function 所以说函数表达式跟变量是一个定义是一个概念
var fun = function(){
console.log(22);
}
//上面代码相当于这几行代码---变量提升
//var fun;
//fun();
//fun = function(){ -因为是变量提升 所以赋值操作无法放在前面
// console.log(22);
//}
</script>
预解析案例
案例1
//案例1 报错这里是因为let要先定义才能使用所以直接走这一步后面就没得走了 Cannot access 'num' before initialization
// let num = 10;
// fun();
// function fun(){
// console.log(num);
// let num = 20;
// }
//let num;
// function fun(){
// let num ;//let标识符无法这样走 因为let不允许再次定义相同的标识符
// console.log(num);
// num = 20;
// }
// num = 10;
// fun();
var倒是可以直接使用
var num = 10;
fun();
function fun(){
console.log(num);//输出undefined
var num = 20;
}
//相当于执行了一下代码
//var num;
//function fun(){
//除了外面全局变量的变量提升外 函数内部还要一次变量提升
//var num ;
//console.log(num);
//num = 20;
//}
//num = 10;
//fun();
案例2
//案例2
var num = 10;
function fn(){
console.log(num);//undefined
var num = 20;
console.log(num);//20
}
fn();
//相当于以下代码
// var num;
// function fn(){
// var num;
// console.log(num);
// num = 10;
// console.log(num);
// }
// num = 10;
// fn();
案例3
//案例3
var a = 18;
f1();
function f1(){
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
//相当于
// var a;
// function f1(){
// var b;
// var a;
// b = 9;
// console.log(a);//undefined
// console.log(b);//9
// a = '123';
// }
// a = 18;
// f1();
案例4:面试题
// //案例4
f1();
console.log(c);//9
console.log(b);//9
console.log(a1);//报错a1 is not defined
function f1(){
var a1 = b = c =9;
//上面这行代码相当于 var a = 9;b = 9; c = 9;也就是说 b和没有直接赋值 没有var声明 属于全局变量(看作全局变量)
//我们想要的集体声明应该是这样的var(let) a = 9,b = 9,c = 9;
console.log(a1);//9
console.log(b);//9
console.log(c);//9
}
//相当于
// function f1(){
// var a;
// a = b = 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);//undefined
/*
我们继续滤清概念再看 全局变量
console.log(c);//c is not defined
console.log(b);
console.log(a);
f1();刚刚之前哪里必须先调用f1()吧a,全局变量b,全局变量c创建出来
function f1(){
var a = b = c =9;
//上面这行代码相当于 var a = 9;b = 9; c = 9;也就是说 b和没有直接赋值 没有var声明 属于全局变量(看作全局变量)
console.log(a);
console.log(b);
console.log(c);
}
*/