javaScript加深理解

首先切记一句话:函数也是对象

创建函数的几种方式:

1.函数声明:

// function 函数名(){

// }
例:
function fn(){
    
}

2.函数表达式:

// var 函数名 = function(){

// }:
var fn = function(){
    
}

3.构造函数创建:

// var 函数名 = new function(){

// }:
var fn = new function(){

}

函数声明和函数表达式的区别:

1.函数声明调用时可以在任意可见位置调用,不管是在函数声明前或函数声明后,函数声明还可以预解析(预加载),还会有函数提升的作用。
2.函数表达式必须先定义,后调用。

上面提到了预解析,就说一下预解析:

所谓预解析,字面意思就是提前解析代码。就是在当前作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义。
举个例子:
var a = 10
这行代码告诉我们浏览器在全局作用域中有一个a的变量了,如果一个变量只是声明了,但是没有赋值,默认就是undefined, a=10,意思就是给变量进行赋值,a的值是10。
var声明的变量和function声明的函数在预解析的时候有区别,var声明的变量在预解析的时候只是提前的声明,function声明的函数在预解析的时候回提前声明并且会同时定义,也就是说var声明的变量和function声明的函数的区别是在声明的同时没有同时进行定义。
预解析只发生在当前的作用域下,程序最开始的时候,只对window渲的变量和函数进行预解析,只有函数执行的时候才会对函数中的变量和函数进行预解析。
看代码:

console.log(a)
var a = 10;
console.log(a)
fn(10,20)
function fn(m,n){
var total = m+n
console.log(total)
}

然后看输出结果:
在这里插入图片描述

第一次输出a的时候,由于预解析的原因,只声明了还没有定义,所以会输出undefined;第二次输出a的时候,已经定义了,所以输出10。

由于函数的声明和定义是同时进行的,所以fn()虽然是在fn函数定义声明处之前调用的,但是依然可以正常的调用,会正常输出30。

提到预解析,我有想起了作用域: 作用域分 全局作用域 局部作用域 和 块级作用域

全局作用域:

var a = 5;
function fn() {
    b = 10;
    console.log(a);
}
console.log(a);
console.log(b);

1.定义在全局(window)下的变量拥有全局作用域;
2.所有末定义直接赋值的变量自动声明,并拥有全局作用域;
3.所有window对象上的属性,具有全局作用域。

局部作用域:

function fn() {
    var b = 10;
    console.log(b);
}
console.log(b);

局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部;
块级作用域其实也可以算一种局部作用域。
块级作用域:
所声明的变量在指定块的作用域外无法被访问;
在一个函数内部;
在一个代码块(由一对花括号包裹)内部。

let arr = [1, 2, 3, 4, 5];
for(let i in arr) {
    console.log(i); // 1 2 3 4 5
}
console.log(i); // i is not defined

// 对于for循环,圆括号内与花括号内是两个作用域。
for(let j in arr) {
    let j = '1';
    console.log(j); // 1* 5
}

说到作用域我又想起来作用域链 什么是作用域链?

当我们在局部/块级作用域中,调用一个外部的变量时,就会产生作用域链。
当我们在一个函数内部访问当前作用域内不存在的变量时,就会逐层向外查找,如果一直没有找到就会报错。
对于函数而言,函数在哪里创建,它就会从哪里开始向上查找变量;而不是函数在哪里调用。
最常见的就是闭包,通过闭包定义的函数来访问函数的内部变量。

猜你喜欢

转载自blog.csdn.net/weixin_45616142/article/details/108012842