2018-06-27 (函数 作用域)
2018-06-27 本文已影响0人
Mo_ham_med
javascript 函数 作用域
作用域 是能够 产生 作用的 范围, 每种语言 都会 存在 作用域。
特征
java 和 c : (应该是 java 和 c 语言)
作用域 为 代码块, 只要 用 大括号 进行 包裹, 就是 独立的 作用域。
class Person{
public static void main(String args[]){
{
String name = "godme";
System.out.println(name);//true
}
System.out.println(name);//false
}
python 和 javascript
方法 为 作用域 的 最低级别, 往下 不可 分割。
def t ();
if 1 = 21 ;
name = 'godme'
print(name)
()
行为:
在 作用域中 定义的 新东西, 只会 在 作用域 里面 作用,作用域以外,早已被销毁。
作用域链
作用域中 可能 存在 作用域, 就是 函数 中 定义了函数,作用域 于是 存在 层级关系。
作用域链 特性。
1. 查找方式: 访问变量时,从 最低级向上依次查找,直到找到全局变量,找到就立即返回使用,
找不到就报错。
name = 'godme';
function test (){
var name = 'juda9';
function inner(){
var name = 'forev';
}
}
值得 注意的是 内部定义函数 的 加载。
一般 变量加载 只是 声明了,到真正执行的时候才进行值得初始化。
但是,只要定义了函数,哪怕函数放置在最后面,前面的语句也能够进行访问。
function test (){
alert(inner);
function inner(){}
}
所以 可以确定 函数 内部的工作流程。
1. 加载:
(1) 全局变量: 存在全局变量不操作。
(2) 布局变量: 进行声明操作,执行到 关键语句在进行 赋值 初始化操作。
(3) 内部函数: 定义变量 且 携带值 , 值 为 函数体。
2. 执行:
(1) 全局变量: 直接操作。
(2) 局部变量: 有初始化则进行操作,未初始化职位 undefined
(3) 内部函数: 可 直接操作, 函数名可直接作为变量,值为 函数体。
因此, 函数 加载时 进行了 内部量 的 清单化, 具体执行 依照 清单执行。
function test (age){
console.log(age);
var age = 33;
console.log(age);
function age(){}
console.log(age)
}
test(3)
输出 结果 为 function age(){} , 33 , 33
清单中 确定 的 同名 , 清单 中的 age 只会是 函数。
接下来 age 声明赋值, 覆盖 外部 传参。
后面的函数没其他作用了,在加载过程中, 已经 完成了 解析。
变量的声明: 加载 函数时, 会先将 作用域内的 变量 先 进行 声明。
test 测试
function test (){
console.log(name)
var name = 'aaa';
}
test() test 这个 单词 的 意思 是 测试。
打印 undefined, 声明 但是 未被初始化
3. 加载 不执行 : 加载时 只是 确定关系, 具体 数据加载完毕后 确定。
function test(){
var name = 'aaa';
function xx(){
console.log(name)
}
name = 'bbb';
}
test() // bbb
4. 关系固定:加载完成后,作用域关系就固定了,后续的操作依旧延续初始的关系
function add (num){
function calc(input){
return num + input;
}
return calc;
}
关系固定以后,内部被返回的函数就相当于一个汉奸,对外部暴露了一个接口
返回的内部定义的函数,可以访问上一级作用域中的变量,从而可以定制特殊的方法,这就是闭包
闭包在编程语言中普遍存在,重要的意义在于作用域链赋予的特殊层级关系可以让两个函数相互影响,定制特殊函数
python中的装饰器也是闭包的运用