JavaScript的作用域
作用域
代码中的名字,在代码中的可用性范围就是作用域
*作用域用于提高程序逻辑的局部性,增强了程序的可靠性,减少了名字的冲突*
在ES6之前,程序拥有全局作用域和局部作用域
全局作用域
- 整个script标签范围内 或者 是一个 单独的js文件,在整个应用程序中都有效
局部作用域
1.在函数内部的,只在函数内部起效果和作用
function fn(){
//局部作用域
}
*在不同作用域下的变量不会冲突,在同作用域下的变量会产生冲突
变量的作用域
根据作用域的不同,变量可以分文全局变量和局部变量
全局变量
在全局作用域下的变量,在全局范围内都可以使用
在函数内部未声明但是直接赋值的变量,属于全局变量
局部变量
在局部作用域下的变量,只在当前的作用域范围内可以使用
或者
在函数内部定义的变量,只能在函数内部使用
*函数的形参属于局部变量
全局变量和局部变量
- 全局变量:只有在浏览器关闭时才会销毁,常驻内存中,比较占内存资源
- 局部变量:当我们程序执行完毕就会销毁,比较节约内存资源
作用域
在JavaScript中没有块级作用域
JavaScript在ES6中新增了块级作用域
作用域链
*根据内部函数可以访问外部函数变量的机制,JavaScript使用链式查找决定哪些数据能被内部函数访问,这种结构称为 作用域链(就近原则)
作用域链可以通过链式图进行作图分析
JavaScript 预解析
为什么要了解预解析
//1 未定义变量输出
console.log(num); => error : not defined
//2 先输出后定义
console.log(num); => undefined
var num = 10;
//3 调用函数输出
function fn(){
console.log(11); => 11
}
fn();
//4 调用函数表达式后再定义
fun();
var fun = function(){
console.log(22); => fun is not a function
}
JavaScript引擎的运行
分为2个步骤:预解析和代码执行
- 预解析:JavaScript引擎会把代码中所有的
var
和function
提升到当前作用域的最前面 - 代码执行:按照代码书写的顺序从上往下执行
预解析
预解析分为 变量预解析(变量提升)
和 函数预解析(函数提升)
- 变量提升: 把所有的变量声明提升到当前作用域的最前面 *不提升赋值操作
- 函数提升: 把所有的函数声明提升到当前作用域的最前面 *不调用函数
*函数表达式的调用必须写在该表达式的定义和赋值之后
JavaScript对象
对象
对象是一个具体
的事物,是一组无序的相关属性的方法的集合,所有的事物都是对象
使用对象可以更清晰更强大的表达更复杂的结构,使得结构更加直观
属性
属性:事物的特征,在对象中使用属性来表示(常为名词)
方法
方法:事物的行为,在对象中使用方法来表示(常为动词)
创建对象的3种方式
利用字面量创建对象
- 创建对象
对象字面量:{}
花括号,里面包含了表达这个事物的属性和方法
var obj = {}; //创建一个空对象
var obj = { //创建一个复杂对象
uName : 'a', //属性
age : 18,
sex : 'boy',
say: function(){ //方法
console.log('hi~');
}
};
- 里面的属性或者方法,采用键值对的形式
- 属性名 : 值
- 方法名 : 函数
- 对个属性或者方法之间使用逗号
,
隔开 - 方法冒号后面跟的是一个匿名函数
- 使用对象
-
调用对象的属性
-
对象名.属性名 => 对象名的属性
console.log(obj.uName);
-
对象名[‘属性名’]
console.log(obj['uName']);
-
-
调用对象的方法
-
对象名.方法名
obj.say(); //注意必须添加小括号
-
利用 new Object创建对象
var obj = new Object(); //创建一个空对象
//添加属性
obj.uname = 'a';
obj.age = 18;
obj.sex = 'boy';
//添加方法
obj.say = function(){
console.log('say');
}
- 利用
=
等号赋值的方式 添加对象的属性和方法 - 每个属性和方法之间使用
;
分号结束
利用构造函数创建对象
使用构造函数可以更方便的创建和管理对象
构造函数 就是把对象中一些相同的属性和方法抽象出来并封装的函数里面
//定义构造函数
function 构造函数名(){
this.属性 = 值;
this.方法 = function(){};
};
//调用构造函数
new 构造函数名();
//示例:
//定义构造函数
function Star(uname,age,sex){
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang){
console.log(sang);
}
}
//创建对象
var a = new Star('a',18,'boy');
//使用属性
a.name;
//调用函数
a.sing('s');
- 构造函数的函数名首字母需要大写
- 构造函数不需要 return 就可以返回结果(Object 对象)
变量、属性、函数、方法的区别
- 变量和属性的相同点
- 用来存储数据的
- 变量和属性的不同点
- 变量 单独声明并赋值 使用的时候变量名 单独存在
- 属性 在对象内部,不需要声明 使用的时候必须通过对象引用
- 函数和方法的相同点
- 用于实现某种功能的代码段
- 函数和方法的区别
- 函数 单独声明 并且通过函数名()调用 单独存在
- 方法 在对象内部定义 使用的时候必须通过对象引用
for … in … 遍历对象
//语法
for(变量 in 对象){
....
}
for(var k in obj){
console.log(k); //属性名
console.log(obj[k]); //属性值
}