1. 函数
- 在实际开发中,经常会使用一个变量来接收函数返回的结果。
- return 有终止函数的作用,return 后的语句不会被执行。
- return 只能返回一个值。(有多个时返回最后一个)
- 所以当要 return 返回多个时,可以使用数组:
return [num1+num2,num1*num2]
函数都有返回值。若有,则返回 return 后的值;若没有,则返回 undefined。
- arguments 的使用: ( 注意:只有函数才有 arguments)
- 当不确定有多少个参数传递的时候,可以用 arguments 来获取。在 JS 中,arguments 实际上是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。
arguments 的展示形式是一个伪数组,因此可以进行遍历。
伪数组的特点: (伪数组并不是真正意义上的数组)
具有 length 属性;
按索引方式存储数据;
不具有数组的 push,pop 等方法。
代码从上往下执行。当执行到调用某函数时,会去找执行部分的代码,如下面的 函数中调用另一个函数:
function fn1() {
console.log(111) /* 第1个执行 */
fn2()
console.log('fn1') /* 第4个执行 */
}
function fn2() {
console.log(222) /* 第2个执行 */
console.log('fn2') /* 第3个执行 */
}
fn1(); /* 先找到这里 */
// 执行顺序:
// 从上往下,fn1和fn2的代码块都未调用,所以这两个代码块都先不管。
// 所以1.先走到fn1(); =>找到fn1代码块=>执行并输出111。
// 2.又走到fn2()=>所以去找fn2代码块=>执行并输出222,fn2。
// 3.回去接着执行并输出fn1。
2. JS 作用域
就是代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性,更重要的是减少命名冲突。
在 ES6 之前:全局作用域,局部作用域(也叫函数作用域)。两者就算名字一样也互不影响。
注意:函数的形参也可以看作局部变量。
从执行效率来说,
- 全局变量:只有在浏览亲关闭的时候才会销毁。比较占内存资源。
- 局部变量:当程序执行完之后就会销毁。比较节约内存资源。
块级作用域:ES6 新增的,原本 JS 中没有块级作用域。
作用域链: (就近原则)
- 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值。这种结构就叫作用域链。
3. JS 预解析
JS 引擎运行 JS 分为两步:预解析、代码执行。
预解析:JS 引擎会把 JS 里所有的 var 和 function 提升到当前作用域的最前面。
- 变量预解析(变量提升):就是把所有的变量声明提升到当前作用域的最前面,不提升赋值操作。
- 函数预解析(函数提升):就是把所有函数声明提升到当前作用域的最前面,不调用函数。只有函数声明形式才有函数提升。
- 函数提升优先级高于变量提升。
// 1.下面的输出结果是什么:
console.log(num);
var num = 10;
// 其实相当于下面的代码:
var num;
console.log(num); /* 所以undefined */
num = 10;
// 2.下面的输出结果是什么:
fun();
var fun = function() { /* 函数表达式声明的是变量名不是函数名 */
console.log(22)
}
// 其实相当于下面的代码:
var fun;
fun();
fun = function() { /* 函数表达式声明的是变量名不是函数名 */
console.log(22) /* 所以报错 */
}
// 3.为什么调用写在最前面也可以:
fn();
function fn() {
console.log(11); /* 因为函数提升,把函数声明提升到当前作用域的最前面。 */
}
// 例子1 :
var num= 10
fun();
function fun() {
console.log(num);
var num = 20;
}
// 相当于执行下面的代码:
var num; /* 外层的变量提升 */
function fun() { /* 外层的函数提升 */
var num; /* 里层的变量提升 */
console.log(num); /* undefined,因为就近原则 */
num = 20;
}
num = 10;
fun();
// 例子2 :
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
// 相当于执行下面的代码:
var num;
function fn() {
var num;
console.log(num); /* undefined,就近原则 */
num = 20;
console.log(num); /* 20 */
}
num = 10;
fn();
// 例子3 :
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
// 相当于执行下面的代码:
var a;
function f1() {
var b;
b = 9;
var a;
console.log(a); /* undefined */
console.log(b); /* 9 */
a = '123';
}
a = 18;
f1();
// 例子4 : 这道题需要注意
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
// 这句相当于var a =9; b = 9;c = 9; 而不是var a;var b;var c;
// 所以b、c并没有声明!!! 要当全局看
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
// 相当于执行下面的代码:
function f1() {
var a;
a = b = c = 9;
// var b; 不是这样,写错了。。。
// var c;
// a = 9;
// b = 9;
// c = 9;
var a;
console.log(a); /* 9 */
console.log(b); /* 9 */
console.log(c); /* 9 */
}
f1();
console.log(c); /* 9 */
console.log(b); /* 9 */
console.log(a); /* undefined,局部变量 */
- 代码执行:按照代码顺序从上往下执行。
4. 对象
在 JS 中,对象是一组无序的相关属性和方法的集合,所有事物都是对象,如数组、字符串、函数、数值。
对象是由属性和方法组成的。
属性:是事物的特征,在对象中用属性来表示。(常用名词)
方法:是事物的行为,在对象中用方法来表示。(常用动词)
为什么需要对象:
- 保存一个值时,可以使用变量,保存多个值时,可以使用数组,如果要保存一个人的完整信息嘞~
现阶段可以用三种方式创建对象:
- 字面量创建;
- new Object 创建对象;
- 利用构造函数创建对象。
5. 类 class
- 在 ES6 中新增了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。
- 类抽象了对象的公共部分,它泛指某一大类(class)。
- 对象特指某一个,通过类实例化一个具体的对象。
5.1 创建类
语法:
class name {
//class body
}
创建实例:
var xx = new name();
注意:类必须使用 new 实例化对象。
5.2 类 constructor 构造函数
- constructor() 方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过 new 命令生成对象实例时,自动调用该方法。如果没有显式定义,类的内部会自动创建一个 constructor()。
- 有了它就不用 return。
例:
// 1.创建类class,创建一个Star类。
class name {
constructor(uname) {
// this指向创建的实例:
this.uname = uname; /* 将uname指向创建的实例,这样就接收了这个参数 */
this.age = age;
}
sing(song) {
console.log('略略略');
console.log(this.name + song);
}
}
// 2.利用类创建对象 new
var zs = new Star('张三',18); /* 只要加了new,就自动调用constructor。 */
var ls = new Star('李四',20);
console.log(zs); /* 输出张三 */
console.log(ls);
zs.sing('lost river');
zs.sing('///////');
注意点:
- 通过 class 关键字创建类,类名要大写。
- 类里面有个 constructor 函数,可以接受传递过来的参数,同时返回实例对象。
- constructor 函数只要 new 生成实例时,就会自动调用这个函数,如果不写这个函数,类也会自动生成这个函数。
- 生成实例,new 不能省略。
- 最后注意语法规范,创建类,类名后面不要加小括号,生成实例,类名后面要加小括号,构造函数不需要加 function。
另外:
- 类里面所有的函数都不用写 function 来声明。
- 类里面,所有函数/方法之间不能加逗号分割。
5.3 类的继承
下次更新写。