TypeScript--函数作用域

函数作用域

1. 什么是函数作用域?

个人理解:类似于玄幻小说里的气场或域,在该范围内受到某种效果,这个函数就是类似于这个效果,只有在该范围有用

function ShuaiGuo():void{
    var name:string = '刘德华'
    console.log(name)
}
ShuaiGuo()
console.log(name)

个人理解:函数放在内存的代码段里,而内存垃圾清理最常用机制之一标记清除(另一个是引用计数),当函数执行的时候标记为“进入环境”,当函数执行结束会变成“离开环境”变量后会被销毁,下面的引用找不到

2. 什么是全局变量?

个人理解:我们写代码时候命名要见名知意---从字面上理解“全局”函数向上寻找是window,在window下的变量,在函数内可以调用,函数外也可以调用

var name:string = '刘德华'
function ShuaiGuo():void{
    console.log(name)
}
ShuaiGuo()
console.log(name)

3. 什么是局部变量?

局部,天气预报经常说局部地区有雨,相对整个全局的某一部分有雨,这个范围准确的说是,作用域的范围

【注】

当局部变量和全局变量重名的时候,函数体内变量是起作用的;如果重名会导致:变量提升

var name:string = '刘德华'
function ShuaiGuo():void{
    //var name:string (声明为空)
    console.log(name)//1. undefined  
    var name:string = '滑的溜'
    console.log(name) //2. 滑的溜
}
ShuaiGuo()
console.log(name)//3.刘德华 
【扩展】

3.1 什么是函数提升?(ES5)

  • 函数声明
  • 函数表达式
【注】只有函数声明才存在函数提升,函数提升比变量提升优先级高

函数声明语法

f('superman');
function f(name){
    console.log(name);
}

运行上面的程序,控制台能打印出supemran。

函数表达式语法

f('superman');
var f= function(name){
    console.log(name);
}

运行上面的代码,会报错Uncaught ReferenceError: f is not defined(…),错误信息显示说f没有被定义。

为什么同样的代码,函数声明和函数表达式存在着差异呢?

这是因为,函数声明有一个非常重要的特征:函数声明提升,函数声明语句将会被提升到外部脚本或者外部函数作用域的顶部(是不是跟变量提升非常类似)。正是因为这个特征,所以可以把函数声明放在调用它的语句后面。如下面例子,最终的输出结果应该是什么?:

var getName = function(){
    console.log(2);
}
function getName (){
    console.log(1);
}
getName();

可能会有人觉得最后输出的结果是1。让我们来分析一下,这个例子涉及到了变量声明提升和函数声明提升。正如前面说到的函数声明提升,函数声明function getName(){}的声明会被提前到顶部。而函数表达式var getName = function(){}则表现出变量声明提升。

因此在这种情况下,getName也是一个变量,因此这个变量的声明也将提升到底部,而变量的赋值依然保留在原来的位置。需要注意的是,函数优先,虽然函数声明和变量声明都会被提升,但是函数会首先被提升,然后才是变量。因此上面的函数可以转换成下面的样子:

function getName(){    //函数声明提升到顶部
    console.log(1);
}
var getName;    //变量声明提升
getName = function(){    //变量赋值依然保留在原来的位置
    console.log(2);
}
getName();    // 最终输出:2

所以最终的输出结果是:2。在原来的例子中,函数声明虽然是在函数表达式后面,但由于函数声明提升到顶部,因此后面getName又被函数表达式的赋值操作给覆盖了,所以输出2。

3.2 let关键字变量的作用域(ES6)

在ES5中,变量作用域只有全局和局部,并且是以函数划分,在javascript语言中,并不适合大型开发,因为很容易内存泄露,javascript团队,在ES6中推出了let关键字(生成一个块级作用域,程序更有条例,简洁优雅,但是感觉可读性会下降了很多)

function ShuaiGe():void{
    var nameA:string = "刘德华"
    {
        let nameB:string = '古天乐'
        congsole.log(nameB)
    }
    congsole.log(nameA)
    congsole.log(nameB)
}
ShuaiGe()