获取当前日期输入当年第几天
//输入,年月日,获取这个日期是这一年的第几天 //年-月--日:20171月31日 function getDay(year,month,day){ //定义变量存储对应的天数 var days=day //如果用户输入的是一月份,没有必要向后算天数,直接返回天数 if(month==1){ return days; } //代码执行到这里--用户输入的不是1月份 //比如输入的是4月份23日---1,2,3,+23 //定义一个数组,存储每个月的天数 var months=[31,28,31,30,31,30,31,31,30,31,30,31]; //获取到当前数的第三个月(索引:0,1,2)所以i<month-1 for(var i=0;i<month-1;i++){ //将输入的天数相加到一起 days+=months[i] } //需要判断这个年份是不是闰年并且是否大于2 if(isLeapYear(year)&&month>2){ //那就在days加上1天 days++; } return days; } //判断这个年份是不是闰年 function isLeapYear(year){ return year%4==0&&year%100!=0||year%400==0; } //2000年闰年31+29+2 62 console.log(getDay(2000,3,2));//62
arguments对象:arguments
是一个对应于传递给函数的参数的类数组对象。
MDN:
arguments
对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments
对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:
arguments[0] arguments[1] arguments[2]
参数也可以被设置:
arguments[1] = 'new value';
arguments
对象不是一个 Array
。它类似于Array
,但除了length属性和索引元素之外没有任何Array
属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的Array
:
var args = Array.prototype.slice.call(arguments); var args = [].slice.call(arguments); // ES2015 const args = Array.from(arguments); const args = [...arguments];
对参数使用slice会阻止某些JavaScript引擎中的优化 (比如 V8 - 更多信息)。如果你关心性能,尝试通过遍历arguments对象来构造一个新的数组。另一种方法是使用被忽视的Array
构造函数作为一个函数:
var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
如果调用的参数多于正式声明接受的参数,则可以使用arguments
对象。这种技术对于可以传递可变数量的参数的函数很有用。使用 arguments.length
来确定传递给函数参数的个数,然后使用arguments
对象来处理每个参数。要确定函数签名中(输入)参数的数量,请使用Function.length
属性。
属性
-
arguments.callee
- 指向当前执行的函数。
-
arguments.caller
- 指向调用当前函数的函数。
-
arguments.length
- 指向传递给当前函数的参数数量。
-
arguments[@@iterator]
- 返回一个新的Array迭代器对象,该对象包含参数中每个索引的值。
-
function f1(){ //获取的是函数在调用的时候,传入了几个参数 console.log(arguments.length) //使用arguments对象可以获取传入的每个参数的值 console.log(arguments) } f1(10,20,30,40);//调用 function f2(){ var sum=0; arguments[1]=60; for(var i=0;i<arguments.length;i++){ sum+=arguments[i]; } return sum; } console.log(f2(10,20,30,40,50))
函数其他定义方式:
/* *命名函数:函数如果有名字就是命名函数 * *匿名函数:函数如果没有名字,就是匿名函数 * *函数的另一种定义方式 *函数表达式 *把一个函数给一个变量,此时形成了函数表达式 *var 变量=匿名函数 *var f1=function(){ * *} *如果是函数表达式,那么此时前面的变量中存储的就是一个函数 *而这个变量就相当于是一个函数,就可以直接加小括号调用了 * *注意: *函数表达式后,要加分号; */ //将匿名函数给了变量 //函数表达式 var f2= function (){ console.log("匿名函数的调用") } f2(); //函数表达式 var f3= function (){ console.log("我是一个匿名函数") } // var f1=function f4(){console.log("萌萌啊")}; // f1(); //函数调用自身没有写出来 // (function(){console.log("萌萌啊");})();
函数数据类型
function f1(){ console.log("我是函数"); } //如何获取某个变量的类型?typeof console.log(typeof f1) //函数是有数据类型,数据类型:function类型的
函数作为参数传递时
声明一个函数 function f1(){ console.log("这是一个函数") } function f2(fn){ fn();//函数调用----说明fn变量中存储是一个函数 } f2(f1) function sayHi(fn){ console.log("函数作为参数木有调用前") fn();//当前fn变量存储的为一个函数 } function mengSay(){ console.log("努力啊!小伙子"); } sayHi(mengSay) //函数作为返回值使用 function fn(){ console.log("fn函数调用了"); return function (){ console.log("我是一个匿名函数"); } } //fn()//调用 var jieShou=fn();//将fn函数赋值给变量jieShou jieShou();//实际调用函数
js作用域
*全局变量:声明变量是使用var声明的,那么这个变量就是全局变量,全局变量*可以在页面的任何位置使用*除了函数以外,其他的任何位置定义的变量都是全局变量*局部变量:在函数内部定义的变量,是局部变量,外面不可以使用*全局变量如果页面不关闭,那么就不会释放,就会占空间,消耗内存****块级作用:一对大括号就可以看成是一块,在这块区域中定义的变量,只能在这个*区域中使用,但是js中在这个块级作用域中定义的变量,外面也可以使用*说明:js中没有块级作用域,只有函数除外**隐式全局访问:声明的变量没有var,就叫隐式变量*全局变量是不能被删除,隐式全局变量是可以被删除*定义变量使用var是不会被删除的,没有var是可以删除的if(true){ var num=10; } console.log(num);//可以使用 for(var i=1;i<100;i++){ var number=100; } console.log(number);//可以使用 function f1(){ var ceShi=1000; } // console.log(ceShi)//不能使用 var num1=10; num2=20; delete num1;//不可以删除 delete num2;//可以删除 console.log(typeof num1); console.log(num1+10); console.log(typeof num2);
作用域链:
//js作用域链 //从函数的作用域内开始,如果当前不存在变量,逐层向上找 //如f1函数中 f3函数如果找不到num;就会向上f2函数找num.....逐层 var num=10; function f1(){ var num=20; function f2(){ var num=30; function f3(){ var num=40; console.log(num) } } }
预解析
//预解析:提前解析代码 console.log(num);//undefined //把变量的声明提前了 var num=10;
预解析中,变量的提升,只会在当前作用域中提升,提前到当前作用域的最上面函数中的变量只会提前到函数的作用域中的最前面,不会出去预解析会分段,预解析的时候不同的script标签,同名的函数不会冲突function f1(){ console.log(num);//undefined; var num=10; } f1(); console.log(num);//not defined 没有定义
运行结果:
预解析会将变量声明提前 函数声明提前
var a=25; function add(){
// var a; alert(a);//undefined 预解析会将变量声明提前 函数声明提前 即 var a; var a=10; } add();
console.log(a)//25 第一个a是全局变量 可以访问 函数中的a作用域只在add函数中,不可以访问预解析会将变量a提前声明,同时也将函数a()提前声明,即a不会等于undefined,因为a重名,所以已经被函数a()覆盖(暂时这样理解)
console.log(a); // function a(){ // console.log("aaaaa"); // } function a(){ console.log("aaaaa"); } var a=1; console.log(a);//1
预解析会先将变量提前声明,再到函数提前声明,根据作用域链(先作用域内查找变量再逐层向上)——————script标签内的变量先提前声明——————>再到函数提前声明————>函数内作用域:变量也会提前声明——————>一步一步结果如下:
var a=10; //预解析 // var a; a=10 // function f1(){ // var b; var a;b=9; // var b=9; // console.log(a)//因为预解析 // console.log(b) // var a="123"; // } f1() function f1(){ var b=9; console.log(a)//因为预解析 console.log(b) var a="123"; } f1();
案例分析:局部变量和隐式变量
function f1(){ var a=b=c=9; /* var a;//函数内声明的 局部变量 a=9; b=9;//隐式变量 c=9;//隐式变量 */ console.log(a);//9 console.log(b);//9 console.log(c);//9 } f1(); console.log(a);// not definde 所以报错 console.log(b);//9 console.log(c);//9
//var f1; f1();//不能调用 var f1=function (){//因为f1是变量 声明会提前 console.log(a); var a=10; }