目录
2、预解析分为 变量预解析(变量申明提升) 和 函数预解析(函数提升)
1、使用字面量创建对象,通过声明变量,并对其赋值一个对象来实现
(1)在使用字面量进行赋值之后,我们使用对象时采取 (对象名.属性名)的方式来进行调用 (2)调用属性还有一种方法 对象名['属性名']
(3) 调用对象的 方法(sayHi),使用的是 对象名.方法名()
使用 for in 和 for of来遍历对象,其中的变量名常写作为 key 或 k
一、arguments(伪数组,并不是真正意义上的数组)
arguments的使用,只有函数才有 arguments 对象,而且是每个函数都内置好了这个arguments。
1、特性
1. 具有数组的 length 属性
2. 按照索引的方式进行存储的
3. 它没有真正数组的一些方法 pop() push() sort() 等等
2、arguments 内置对象的优缺点
优点:不需要形参
缺点:不能使用数组api
二、一些arguments的运用
1、利用函数求任意个数的最大值
function max() {
var max = arguments[0]
for (var i = 1; i < arguments.length; i++) {
if (max < arguments[i]) max = arguments[i]
}
console.log(max);
}
2、函数之间的相互调用
function a() {
console.log(1);
b()
}
function b() {
console.log(2);
}
三、声明函数的方法
1. 利用函数关键字自定义函数(命名函数)
function fn() {
console.log(this);
}
fn()
2. 函数表达式(匿名函数)
var fn2 = function (a) {
console.log(this);
}
fn2('a')
3、一些声明函数的事项
(1)函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
(2)函数表达式也可以进行传递参数
(3)函数中的this指向 ,谁调用它它就指谁(匿名,命名函数this指向window)
四、JavaScript的作用域
代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性更重要的是减少命名冲突,js的作用域分为全局作用域和局部作用域。
1、全局作用域:
整个script标签 或者是一个单独的js文件,可以在任何地方调用或使用
2、局部作用域(函数作用域):
在函数内部就是局部作用域,这个变量的名字只在函数内部起效果和作用
3、代码解析:
在下列代码中,a为全局作用域,在整个js文件下进行使用,而b为局部作用域,只能在函数 fn()中进行使用
var a = 5
function fn() {
console.log(a);
var b = 10
console.log(b);
}
fn()
五、变量的作用域
根据作用域的不同,变量也可以分为全局变量和局部变量
1. 全局变量: 在全局作用域下的变量 在全局下都可以使用
注意:在函数内部没有声明直接赋值的变量也属于全局变量
2. 局部变量:在局部作用域下的变量,或者在函数内部的变量
注意: 函数的形参也可以看做是局部变量
var a = 6;
// var b;
function fn(x,y){//var x,y
console.log(a);
var b = 7
console.log(b);
}
fn()
console.log(b);
//在上述代码中,先声明一个全局变量 a = 6
//然后定义一个函数,并赋予其形参一个局部变量
//在函数内部声明了一个局部变量 b = 7
3. 从执行效率来看全局变量和局部变量
(1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
(2) 局部变量 当我们程序执行完毕就会销毁, 比较节约内存资源
块级作用域
js的作用域为全局作用域和局部作用域 ,现阶段js 没有块级作用域,而在 es6 的时候新增了块级作用域
在使用大括号( {} )、if {} 、for {} 时,使用的就是块级作用域
在es6中let,const 都可以声明一个块级作用域,而var可以声明全局变量,let const不行
if (3 < 5) { var num = 10 } // 外面的是不能调用num的 console.log(num);
六、作用域链
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链,其遵循就近原则。
代码解析:
在下列代码的运行中,先声明了三个变量并进行赋值,然后定义一个函数 fn,其中在控制台打印a的值。此时a的值为全局变量 a =10 进行取用。
随后定义一个函数 fn1,其中重新对a进行赋值,此时的a遵循就近原则调用的是 a =20的值。
在fn1中打印变量 b 的值,但是由于在局部 fn1 中没有对其进行声明赋值,所以遵循就近原则后取全局变量 b =30 的值。
(在fn 中声明的b=20属于局部变量,只能在fn函数中进行使用,在进行调用时无法取用)
var num = 1; //全局变量 var a = 10; var b = 30; function fn() { console.log(a); //a = 10 var b = 20; fn1() } function fn1() { var a = 20; console.log(a);//a = 20 console.log(b);//b = 30 } fn()
一些案例:
var num = 456; //全局的变量
function f1() {
var num = 123; //局部变量
f2();
}
function f2() {
// var num = 0; //局部变量 就近原则
console.log(num); // 站在目标出发,一层一层的往外查找
}
//该处代码num的值为全局变量456
需注意定义与调用的区别:
定义一个在其他函数内部的函数时,需注意函数内局部变量的影响,即我们需要向外一层一层的查找。
而在调用函数时,我们需注意使用变量的是声明函数的位置,而非调用函数的位置,即从函数声明的位置出发去查找
var a = 1; //全局的变量
var b = 5
function fn1() {
var a = 2;
var b = '22';
fn2();
function fn2() {
var a = 3;
fn3();
function fn3() {
var a = 4;
console.log(a);//4
console.log(b);//"22"
}
}
}
fn1();
在对这些作用域链的了解中,只需进行初步了解原理和使用即可,在完整的项目中不会进行多层嵌套的情况出现。
七、预解析
1、在运行js文件时,我们先进行预解析后才执行代码
(1). 预解析时js引擎会把js里面所有的 var 还有 function 申明,提升到当前作用域的最前面
(2). 代码执行时按照代码书写的顺序从上往下执行
2、预解析分为 变量预解析(变量申明提升) 和 函数预解析(函数提升)
(1) 变量提升:把所有的变量声明提升到当前的作用域最前面 ,不提升赋值操作
(2) 函数提升:把所有的函数声明提升到当前作用域的最前面 ,不调用函数
需注意预解析和作用域链的搭配使用会导致原有的一些代码赋值和声明的改变,我们在进行预解析时会将代码中的函数和变量进行重新排序,来达成特定的运行顺序。
当进行一次预解析之后,代码的格式发生改变,此时我们再根据代码的作用域链来对代码中变量和函数的输出结果来进行尝试。
八、利用对象字面量创建对象
1、使用字面量创建对象,通过声明变量,并对其赋值一个对象来实现
var obj = {}; // 创建了一个空的对象
var obj1 = new Object()
(1) 里面的属性或者方法我们采取键值对的形式 键 属性名 : 值 属性值
(2) 多个属性或者方法中间用逗号隔开的
(3) 方法冒号后面跟的是一个匿名函数
var obj = {
name:"a",
age:18,
sayHi:function(){
console.log("Hi");
console.log(this);
},
}
//需注意在函数中所有的声明方法所返回的 this 值都为
2、使用对象
(1)在使用字面量进行赋值之后,我们使用对象时采取 (对象名.属性名)的方式来进行调用
(2)调用属性还有一种方法 对象名['属性名']
(3) 调用对象的 方法(sayHi),使用的是 对象名.方法名()
在JavaScript中,对象的方法是指绑定到对象上的函数。方法可以访问和操作对象的属性,也可以执行与对象相关的操作。方法通常是对象字面量的一部分,作为对象的属性值来定义。
变量、属性、函数、方法的区别
1.变量和属性的相同点
变量:单独声明并赋值 ,使用的时候直接写变量名,单独存在
属性:在对象里面的不需要声明的,使用的时候必须是 对象.属性
2. 函数和方法的相同点 都是实现某种功能 做某件事
函数:单独声明,并且调用的,函数名() 单独存在的
方法:在对象里面 调用的时候是 对象.方法()
3、使用构造函数的方法来构造对象
// 利用 关键字 + 数据类型 来创建对象
//即使用 new + Object 来创建对象
var obj = {}
var obj1 = new Object()
console.log(obj, obj1);
// (1) 我们是利用 等号 = 赋值的方法 添加对象的属性和方法
// (2) 每个属性和方法之间用 逗号 隔开
obj1 = {
uname: "a",
age: 18
}
为什么要使用构造函数
前面两种创建对象的方式一次只能创建一个对象,当创建多个对象时,里面很多的属性和方法是大量相同的,我们只能复制。
因此我们可以利用函数的方法 重复这些相同的代码 我们就把这个函数称为构造函数,又因为这个函数不一样,里面封装的不是普通代码,而是一个对象:构造函数,就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面 。
//构造函数 function People(name, age, sex) { this.name = name this.age = age this.sex = sex this.sing = function (song) { console.log(song); } } //实例化 实例 var ldh = new People("刘德华", 35, "男") var gfc = new People("郭富城", 35, "男") var lm = new People("黎明", 35, "男") var zxy = new People("张学友", 35, "男") console.log(ldh); console.log(gfc); console.log(lm); console.log(zxy); ldh.sing("恭喜发财") // function 构造函数名() { // this.属性 = 值; // this.方法 = function() {} // } // new 构造函数名();
构造函数的一些方法
1. 构造函数名字首字母要大写
2. 我们构造函数不需要return 就可以返回结果
3. 我们调用构造函数 必须使用 new
4. 我们只要new Star() 调用函数就创建一个对象
5. 我们的属性和方法前面必须添加 this
6. 我们利用构造函数创建对象的过程我们也称为对象的实例化
九、关键字执行的过程
new关键字执行过程
(1)new 构造函数可以在内存中创建了一个空的对象
(2)this 就会指向刚才创建的空对象 (实例)
(3)执行构造函数里面的代码 给这个空对象添加属性和方法
(4)返回这个对象
十、遍历对象
使用 for in 和 for of来遍历对象,其中的变量名常写作为 key 或 k
在一些特殊场景下,for in 和 for of 会有使用上的区别,for in 会遍历对象的键或者索引号,而for of会直接遍历对象,需要进行区别使用
var arr = [1, 2, 3]
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
for (var i in arr) {
console.log(arr[i]);
}
for (var item of arr) {
console.log(item);
}
var obj = {
name: "a",
age: 18,
sex: "男"
}
for (var key in obj) {
console.log(key + "------" + obj[key]);
}