一、作用域
能起到作用的区域就叫做作用域。定义在不同区域的变量,他的作用域是不一样的。
不在任何一个函数中定义的变量叫全局变量。他的作用域是定义之后的所有文档区域。
例:
<script>
var a = 10
</script>
<script>
console.log(a); // 后面的script标签能用
function fn(){
console.log(a); // 后面的函数中能用
}
fn()
</script>
全局变量 - 定义在函数外的变量 - 作用域是整个页面
局部变量 - 定义在函数内的变量 - 作用域是函数内部
局部可以访问到全局的变量,全局访问不到局部的变量
二、作用域链
作用域链规则
作用域链:由作用域嵌套形成的一条链式结构
规则1:当我们将一个变量当做是一个具体的数据使用的时候,先在当前作用域中找是否定义过这个变量,定义过:直接使用;没有定义过:就去上级作用域中去找,....直到全局,如果全局也没有定义过,报错
规则2:当我们给一个变量空间赋值的时候,先在当前作用域中找是否定义过这个变量,定义过:赋值成功,修改的是当前作用域中的这个变量;没有定义过:就去上级作用域中找,....直到全局,全局找到了,就是在给全局变量赋值,如果全局也找不到,就会在全局定义这个变量并赋值
作用域练习
结论:
全局中有预解析,局部中也有预解析,局部的预解析,只能在局部中进行,不会将变量提升到全局
使用连等的方式定义变量并赋值,只有第一个有定义过程,其余的都是直接赋值
函数定义好以后,函数名就跟变量名一样,可以使用函数名修改这个空间中的值
局部的预解析会在形参赋值之后,预解析中的函数会覆盖掉形参赋的值
三、递归函数
递归函数就是在函数中调用自己。
求阶乘
function fn(n) {
if(n === 1) {
return 1
}
return n * fn(n-1)
}
var s = fn(5)
console.log(s);
四、事件
1、概念
事件中的标签,事件源
js中使用 标签的id名 代表 标签 -- 注意:标签的id名不要用js的关键字
行为类型 - 事件类型 - 用户在网页中进行了哪种行为
代码函数-事件触发后要做的事情
2、语法
标签.on事件类型 = 函数代码
列:
<button id="btn">按钮</button>
<script type="text/javascript">
btn.onclick = function(){
alert("点击了按钮!");
}
</script>
事件类型常用:
事件 | 备注 |
onclick | 当鼠标左键单击 |
ondblclick | 当鼠标左键双击 |
onmouseover | 当光标在指定的内容上面 |
onmouseout | 当光标离开指定的内容 |
onkeydown | 当键盘按下的那一刻 |
onkeyup | 当键盘抬起的那一刻 |
onfocus | 当输入框得到焦点 |
onblur | 当输入框失去焦点 |
onchange | 当指定的标签里面内容有变化的时候 |
onsubmit | 提交事件 |
onload | 当整个网页加载完成后 |
事件的其他写法:
// 给事件赋值函数名称
btn.onclick = fn
function fn(){
console.log('点击了按钮')
}
// 给事件赋值变量名 - 值是函数
var fn = function(){
console.log('点击了按钮')
}
注意:如果给事件赋值函数名,千万不能加小括号调用
事件还可以写在行内:
<!-- 直接在行内写js代码 -->
<button onclick="console.log('点击了按钮')">按钮</button>
<!-- 可以在行内调用函数 -->
<button onclick="fn()">按钮</button>
<script>
function fn(){
console.log('点击了按钮')
}
</script>
注意:在行内的事件中调用函数一定要加小括号调用才行
js可以像css一样有3种写法:
行内写法:事件
内联写法:平常写的代码
外联写法:项目中要将js代码放在一个文件中,在html中引入js文件
<script src="js文件路径"></script>
五、对象
1、概念
复杂的数据 - 一个变量中存储多个数据
表现形式:
var arr = [];
var obj = {};
var none = null;
这三种不同的表现形式指的都是对象。我们让多个不同的值描述一个人,重点看使用{}定义的对象。
2、定义
var obj = {};
这样定义的对象是空数据,其中什么也没有。对象中的值,是由键值对组成。
键值对是指在描述一个事物的时候,需要一个名字,对应一个值,例如:
姓名:张三 // 姓名是键,张三是值
width:100px // width是键,100px是值
border=1 // border是键,1是值
定义有数据的对象,键和值之间使用冒号隔开,键值对之间使用逗号隔开:
var obj = {
name:"张三",
age:12
}
对象中键值对的数量没有限制,可以有任意多个
对象中的键都是字符串,只是正常情况下可以省略引号,但如果键中包含连字符,就不能省略引号了
"province-name":"山东省"
3、对象的基本操作
访问对象中的值:
对象.键 # 这种方式的属性名不用加引号
# 或
对象[键] # 这种方式的属性名必须加引号
对象的遍历:
遍历的意思就是将每一个值都访问一遍。
js提供了专门用来遍历对象的操作语法:
for(var attr in obj){
# 这里的attr代表对象属性名
# obj表示这个对象
}
列:
var obj = {
name:"张三",
age:12,
height:180
};
for(var i in obj){
// 这里的i表示对象的属性名,是一个字符串
console.log(i,obj[i]);
}
注意:遍历对象时,输出对象中的值,必须使用对象[代表键的变量]这种形式来输出。
因为,如果使用.来访问的话,是有歧义的
删除对象中的键值对:
delete 对象.键
delete 对象[键]
例:
var obj = {
name:"张三",
age:12,
height:180
};
console.log(obj);
delete obj.name;
console.log(obj);
delete obj['age']
console.log(obj);
4、方法概念
对象中值的类型是没有限制的,可以是任意类型。当值不是函数的时候,我们将这个键值对叫做对象的属性,当值是一个函数的时候,我们将这个键值对叫做对象的方法。
var obj2 = {
name:'王五',
study:function(){
console.log("在学习");
}
}
console.log(obj2);
name就是对象obj2的属性,study就是对象obj2方法