1.函数提升
程序执行前会将函数提升到所在作用域的最前边
2.递归
在一个函数的内部调用了自身这个函数
如何使用递归:
要有边界条件
结合着return,最终跳出函数
递归:https://www.codece.com/archives/102
3.匿名函数
function (){ }
(1)创建函数
//匿名函数创建函数
//函数表达式
//变量名称fun就是函数名称
var fun = function(){
console.log('ok');
}
//fun(); //ok
//console.log(fun);
结果 ƒ (){
console.log('ok');
}
函数声明function fn(){} |
---|
函数表达式变量名称就是函数名称var fun=function(){} |
对比函数名称()和函数名称
函数名称(),调用函数,得到函数的返回结果。
函数名称,本质上是一个变量,保存了一个函数。
练习:使用函数表达式创建函数,传递任意两个数字,返回两个数字之间所有整数的和。
var getSum = function(n1,n2){
//循环n1~n2
for(var i = n1,sum = 0;i <= n2;i++){
sum += i;
}
return sum;
}
console.log( getSum(1,100) );
对比函数声明和函数表达式创建函数的区别
函数声明创建的函数存在函数的提升,顺序上可以先写调用再写创建
函数表达式创建的函数只是存在变量声明的提升,必须先写创建再写调用
(2)匿名函数自调用
全局污染:全局变量的出现产生的影响
(function(){ 函数作用域下,变量是局部变量,可以防止污染全局})();
```js
//全局污染
//轮播图1
(function(){
//函数作用域,变量都是局部变量
var n = 4;
console.log(n);
})();
//轮播图2
(function(){
var n = 5;
console.log(n);
})();
//轮播图3
(function(str){
var n = 1;
console.log(n,str);
})('WEB2104');
(3)回调函数
将函数以实参的形式传递,这个传递的函数称为回调函数
function tao(madai){
madai() //调用传递进来的回调函数
}
function dong(){ }
tao(dong);
tao( function(){ } )
function tao(madai){
console.log('涛哥开始跑第1棒');
console.log('涛哥到达第1棒终点');
//调用dong
//madai=dong
//madai=function(){}
//调用传递函数,通过形参madai
madai(); //dong() (function(){ })()
}
function dong(){
console.log('东哥开始跑第2棒');
console.log('东哥达到终点');
}
//dong就是回调函数
tao(dong);
//匿名函数也是回调函数
tao( function(){
console.log('陌生人开始跑...');
} );
4.系统函数
isNaN() 检测一个值是否为NaN,常用于检测用户输入的值是否含有非数字
会将检测的值隐式转换为数值,然后查看是否为NaN,是->true 不是->false
var str = '3a';
//会隐式转换为数值,查看是否为NaN
//console.log( Number(str) );
//是否含有非数字
//console.log( isNaN(str) );
//判断str中是否含有非数字,如果含有,打印'非法的数量',否则打印'格式正确'
if( isNaN(str) ){
console.log('非法的数字')
}else{
console.log('格式正确');
}
isFinite() 检测一个值是否为有限值,只有Infinity是无限值,其它所有的值都是有限值, 是有限值 -> true 不是有限值 -> false
console.log( -1/0 );//Infinity 无穷
console.log( 1/3 );
console.log( isFinite(1/3) );
eval() 执行字符串表达式
//执行字符串表达式
var str = 'parseInt(8.5)';
console.log( str );
console.log( eval(str) );
练习:弹出提示框,输入一组字符串表达式,使用eval执行输入这组表达式
//保存用户输入的值
var str = prompt();
console.log( str );
console.log( eval(str) );
5.对象
属于引用类型数据
对象是一组属性和方法的集合
一部手机,属性有品牌、颜色、型号、尺寸… 方法有玩游戏、看视频、办公、购物…
旁边的电扇,属性有品牌、颜色、高度… 方法有吹风、摇头…
一个杯子,属性颜色、容量… 方法存储水…
万物皆对象
(1)分类
自定义对象,用户自己创建的对象
内置对象(ES对象),JS提供的对象
宿主对象,根据不同的执行环境划分
(2)自定义对象创建方式(三种)
对象字面量
内置构造函数
自定义构造函数
//对象字面量
var phone = {
brand: '小米',
color: '黑色',
'id': '小米11',
'made-in': '深圳'
};
//console.log(phone);
(3)对象字面量
{ 属性名: 属性值, 属性名: 属性值 }
属性名中的引号可以省略,如果含有特殊字符必须加引号
练习:创建一个商品对象,包含的属性有编号、标题、价格、是否在售、库存量
var laptop = {
lid: 1,
title: '小米Air',
price: 4199,
isOnsale: true,
'stock-count':200
};
(4)访问属性
对象.属性名
对象[ ‘属性名’ ]
console.log( laptop.lid );
laptop.price = 5799;
console.log( laptop['stock-count'] );
console.log( laptop['title'] );
如果属性名不存在则返回undefined
//访问不存在的属性
//console.log( laptop.pic );//undefined
//添加新的属性
laptop.pic = 'xiaomi.jpg';
console.log(laptop);
*/
练习:创建图书对象,包含的属性有编号,书名,作者,价格;打印出图书的书名,修改图书的价格,添加图书的出版社属性;打印对象
var book = {
bid: 10086,
bookName: '兔子产后护理',
author: '尼古拉斯.涛',
price: 179
};
console.log( book.bookName );
book.price = 199;
book['publish'] = '非洲出版社';
console.log(book);
(5)内置构造函数
new Object()
创建一个空对象,需要单独添加每个属性
//内置构造函数
var emp = new Object();
//需要单独添加属性
emp.eid = 1;
emp.ename = '涛哥';
emp.sex = '男';
//console.log(emp);
(6)遍历属性
依次访问对象中的每个属性
for(var k in emp){
//k 代表属性名
//emp[k] 属性名对应的属性值
console.log(k, emp[k]);
}
for(var k in 对象){ k 代表属性名 对象[k] 属性名对应的属性值}
(2)练习:使用内置构造函数创建对象,添加若干个成绩,遍历对象得到每个成绩,最终计算出总成绩和平均成绩。
//练习:使用内置构造函数创建对象,添加若干个成绩,
//遍历对象得到每个成绩,
//最终计算出总成绩和平均成绩。
//创建对象
var score = new Object();
//添加成绩
score.chinese = 80;
score.math = 90;
score.english = 88;
score.sports = 100;
//console.log(score);
//遍历属性,获取每一个成绩
//键值对
var sum = 0;
//声明变量,用于保存属性的个数
var count = 0;
for(var k in score){
//遍历一次,个数加1
count++;
//console.log(k,score[k]);
//把每一个成绩加到sum
sum += score[k];
}
console.log(sum,count,sum/count);