目录
1.作用域
作用域:通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
JavaScript (ES6前) 中的作用域有两种:全局作用域、局部作用域(函数作用域):
- 全局作用域:整个 script 标签内部或者一个独立的 js 文件
- 局部作用域(函数作用域):作用于函数内的代码环境,就是局部作用域。这个代码的名字只在函数内部起效果。
var num = 10;//全局作用域
console.log(num);
//局部作用域(函数作用域)
function fn() {
//局部作用域
var num = 20;
console.log(num);
}
fn();
// 结果:
// 10
// 20
2.变量的作用域
(1)全局变量:在全局作用域下的变量 在全局作用下都可以使用
注:如果在函数内部 没有声明直接赋值的情况下也属于全局变量
var num = 10;//全局
console.log(num);
function fun1(){
console.log(num);
}
fun1();
(2)局部变量:在局部作用域下的变量 如在函数内部声明的变量
注:函数的形参也可以看作是局部变量
function fun2(){
var num1 = 20;//局部
num2 = 30;//全局
console.log(num1);
}
fun2();
console.log(num2);
// 结果:
// 10
// 10
// 20
// 30
(3)从执行效率来看全局变量和局部变量
- 局部变量 当程序执行完毕就会销毁,比较节约内存资源
- 全局变量 只有当浏览器关闭的时候才会销毁 比较占内存资源
(4)块级作用域
块级作用域:块作用域由 { } 包括,任何一对花括号{}中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。if语句和for语句里面的{ }也属于块作用域。
JS现阶段没有块级作用域,到了ES6的时候才新增了块级作用域。
if (1<6){
var num3 = 50;
}
console.log(num3);//50
3.作用域链(就近原则)
作用域链:内部函数访问外部函数的变量,采用链式查找的方法(即就近原则)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>作用域链</title>
<script>
// 作用域链:内部函数访问外部函数的变量,采用链式查找的方法(即就近原则)。
var num1 = 10;
function fun1(){
var num = 20;
function fun2(){
console.log(num);//20
}
fun2();
}
fun1();
</script>
</head>
<body>
</body>
</html>
4.预解析
javascript解析器在运行JavaScript代码时分两个步骤:预解析和代码执行。
- 预解析:js引擎会把js中所有的var和function提升到当前作用域的最前面。
- 代码执行:按照代码书写顺序从上到下执行。
预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
- 变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。
- 函数提升:就是把所有的函数声明提升到当前作用域的最前面,不调用函数。
// ---------------测试1-------------
console.log(num); //报错 Uncaught ReferenceError: num is not defined
// -------------测试2----------------
console.log(num); // undefined
var num = 10;
// 相当于执行了以下代码
/*
var num;
console.log(num);
num = 10;
*/
// ---------------测试3---------------
function fn() {
console.log(11);
}
fn(); //11
// ---------------测试4----------------
fun(); // 报错
var fun = function() {
console.log(22);
}
// 函数表达式调用必须写在函数表达式的下面
// 相当于执行了以下代码
/*
var fun;
fun(); // Uncaught TypeError: fun is not a function
fun = function() {
console.log(22);
}
*/
预解析案例:
----------------案例1-----------------
console.log('案例1');
var num1 = 10;
fun();
function fun() {
console.log(num1); //undefined
var num1 = 20;
}
//---------原因:运行顺序如下----------
/*
var num1;
function fun() {
var num1;
console.log(num1);
num1 = 20;
}
num = 10;
fun();
*/
----------------案例2-----------------
console.log('案例2');
var num2 = 10;
function fn() {
console.log(num2); //undefined
var num2 = 20;
console.log(num2); //20
}
fn();
//---------------运行顺序如下--------------
/*
var num2;
function fn() {
var num2;
console.log(num2);
num2 = 20;
console.log(num2);
}
num2 = 10;
fn();
*/
-------------案例3--------------
console.log('案例3');
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a); //undefined
console.log(b);
var a = '123'; //9
}
//----------------顺序如下------------------
/*
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
a = 18;
f1();
*/
//----------------案例4----------------
console.log('案例3');
f1();
console.log(c); //9
console.log(b); //9
console.log(a); //报错
function f1() {
var a = b = c = 9;
console.log(a); //9
console.log(b); //9
console.log(c); //9
}
//------------------顺序:-----------------
/*
function f1() {
var a;
a = b = c = 10;
// 相当于 var a = 10; b = 10; c = 10; b 和 c 直接赋值 没有var 声明 当 全局变量看
// 集体声明 var a = 10, b = 10, c = 10;
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
f1();
console.log(c);//9
console.log(b);//9
console.log(a);//报错
*/
5.创建对象
对象是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人可以是“对象”,一个数据库、一张网页、一个与远程服务器的连接也可以是“对象”。
对象表达有利于结构表达更清晰,象是由属性和方法组成的:
- 属性:名词,事物的特征
- 方法:动词,事物的行为
在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object):
- 利用字面量创建对象
- 利用 new Object 创建对象
- 利用构造函数创建对象
5.1 方法一:利用字面量创建对象
(1)方法:利用字面量创建对象
- 里面的属性或者方法采用键值对的形,如 — 键 属性名:值 属性值
- 多个属性或者方法之间用逗号隔开
- 方法冒号后面跟的是一个匿名函数
// 1.利用字面量创建对象
//var obj = {};//创建了一个空对象
var obj = {
uname: '张三',
age:20,
sex:'男',
sayHi:function(){
console.log('hi');
}
}
(2)使用对象:
// (1)调用对象的属性 采用 对象名.属性名
console.log(obj.uname);
// (2)调用属性还有一种方法 对象名['属性名']
console.log(obj['age']);
// (3)调用对象的方法 sayHi 对象名.方法名()
obj.sayHi();
5.2 变量、属性、函数、方法的区别
变量、属性、函数、方法的区别
1.变量和属性的相同点,他们都是用来存储数据的
- 变量:单独声明并赋值,使用的时候直接写变量名,单独存在。
- 属性:在对象里面的,不需要声明的,使用的时候必须是:对象.属性。
2. 函数和方法的相同点,都是实现某种功能做某件事
- 函数:是单独声明的,通过“函数名()”的方式就可以调用
- 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用。
var num = 10;//变量
var obj = {
age: 18,//属性
fn: function() {//方法
}
}
function fn() {//函数
}
console.log(obj.age);//属性调用
5.3 方法二:利用 new Object 创建对象
- new Object() :需要 new 关键字
- 使用的格式:对象.属性 = 值;
- 每个属性和方法之间用分号结束
var obj = new Object(); // 创建了一个空的对象
obj.uname = '张三疯';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function() {
console.log('hi~');
}
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi();
5.4 方法三:使用构造函数创建对象
为什么需要使用构造函数:
- 因为前面两种创建对象的方式一次只能创建一个对象,里面很多的属性和方法是大量相同的,因此我们可以利用函数的方法,重复这些相同的代码,我们就把这个函数称为构造函数。
- 又因为这个函数不一样,里面封装的不是普通代码,而是对象,构造函数就是把对象里面一些相同的属性和方法抽象出来封装到函数里面。
使用构造函数要时要注意以下两点:
- 构造函数用于创建某一类对象,其首字母要大写
- 构造函数要和 new 一起使用才有意义
构造函数的语法格式:
function 构造函数名() { //声明构造函数
this.属性 = 值;//赋值
this.方法 = function() {}
}
new 构造函数名();//调用构造函数
- 构造函数名字首字母要大写
- 构造函数不需要return 就可以返回结果
- 调用构造函数 必须使用 new
- 只要new Star() 调用函数就创建一个对象 ldh {}
- 属性和方法前面必须添加 this,表示当前对象的属性和方法
// 我们需要创建明星的对象 相同的属性: 名字 年龄 性别 相同的方法: 唱歌
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var Eason = new Star('陈奕迅', 20, '男'); // 调用函数返回的是一个对象
console.log(Eason.name);
console.log(Eason['sex']);
Eason.sing('单车');
var JayChou = new Star('周杰伦', 18, '男');
console.log(JayChou.name);
console.log(JayChou.age);
JayChou.sing('稻香');
// 陈奕迅
// 男
// 单车
// 周杰伦
// 18
// 稻香
6.构造函数和对象区别
- 构造函数泛指的某一大类
- 对象特指一个具体的事物
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>构造函数和对象区别</title>
<script>
// 构造函数和对象
// 1. 构造函数 明星 泛指的某一大类 它类似于 java 语言里面的 类(class)
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
// 2. 对象 特指 是一个具体的事物 周杰伦 == {name: "周杰伦", age: 18, sex: "男", sing: ƒ}
var JayChou = new Star('周杰伦', 18, '男'); // 调用函数返回的是一个对象
console.log(JayChou);
// 3. 我们利用构造函数创建对象的过程我们也称为对象的实例化
</script>
</head>
<body>
</body>
</html>
7.new关键字
new 在执行时会做四件事情:
- 在内存中创建一个新的空对象。
- 让 this 指向这个新的对象。
- 执行构造函数里面的代码,给这个新对象添加属性和方法。
- 返回这个新对象(所以构造函数里面不需要return)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
// new关键字执行过程
// 1. new 构造函数可以在内存中创建了一个空的对象
// 2. this 就会指向刚才创建的空对象
// 3. 执行构造函数里面的代码 给这个空对象添加属性和方法
// 4. 返回这个对象(不用return)
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var JayChou = new Star('周杰伦', 18, '男');
</script>
</head>
<body>
</body>
</html>
8.遍历对象属性
for...in 语句用于对数组或者对象的属性进行循环操作。
语法如下:
for (变量 in 对象名字) {
// 在此执行代码
}
//例子
for (var k in obj) {
console.log(k); // 这里的 k 是属性名
console.log(obj[k]); // 这里的 obj[k] 是属性值
}
注:语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>遍历对象</title>
<script>
// 遍历对象 for in
var obj = {
name: '张三',
age: 18,
sex: '男',
fn: function() {}
}
// for in 遍历我们的对象
// for (变量 in 对象) {}
// 我们使用 for in 里面的变量 我们喜欢写 k 或者 key
for (var k in obj) {
console.log(k); // k 变量 输出 得到的是 属性名
// 输出:
// name
// age
// sex
// fn
console.log(obj[k]); // obj[k] 得到是 属性值
// 输出:
// name
// 张三
// age
// 18
// sex
// 男
// fn
// function fn()
}
</script>
</head>
<body>
</body>
</html>
学习来源:黑马pink老师视频
根据视频内容整理出的学习笔记,用于复习查看。