<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//函数的声明提升
/*
js引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。
而函数表达式必须等到代码执行到那一行,才会在执行上下文中生成函数定义
*/
//eg1:
console.log(a);
var a = 100;
fn('小胖');//声明提升
function fn(name){
//var name="小胖";
age=20;
console.log(name,age);
//var age;
}
//网页加载js文件的时候是从头开始的,当执行console打印语句时,
//找不到,所以先赋值给undefined,然后全局找变量a包括函数体fn,将a提取出来
//fn也提取出来,都提取出来之后,fn已经预加载了,所以fn()能够正常打印
//函数的作用域和全局作用域
//在函数中,使用var声明的变量,为局部变量,只能在函数内部访问。
//不使用var声明的变量,为全局变量,在函数外也能使用
//eg2:不适用var
a=10;
function one(){
console.log(a);
a=5;
console.log(a);
}
one();
console.log(a);
//10
//5
//5
//eg3:使用var
var a=10;
function two(){
console.log(a);
var a=5;
console.log(a);
}
two();
console.log(a);
//undefined
//5
//10
/*
作用域:一条数据在哪个范围中可以使用。
作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突
*/
/*
js的变量中,变量的作用域有两种,
一种是全局作用域(全局变量),一种是局部作用域(局部变量),
一个变量是全局变量还是局部变量,主要看变量声明的位置。
局部作用域:
**声明在函数内部,就是这个函数(function)的局部变量。
**使用var在函数内部定义的变量
**局部作用域只能在函数内部访问。
全局作用域:在任何地方都能访问,
**函数外定义的变量拥有全局作用域,
**不使用var定义的变量拥有全局作用域,
**所有window对象上的属性拥有全局作用域
**没有声明在函数内部的函数拥有全局作用域
*/
var a = 100;
function fn(){
var a = 50; //局部作用域
console.log(a); //50
}
console.log(a); //100
/*
**js没有所谓的块级作用域,js的作用域是相对函数而言的,
**可以称为函数作用域
*/
/*
作用域链:根据内部函数访问外部函数变量的机制,
用链式查找方式决定哪些数据能被内部函数访问到。
*/
/*
js执行环境
js为每一个执行环境关联了一个变量对象,
环境中定义的所有变量和函数都保存在这个对象中。
全局环境是最外围的执行环境,全局环境被认为是window对象,
因此所有的全局变量和函数都是作为window对象的属性和方法创建的。
的执行顺序是根据函数的调用来决定的,当一个函数被调用时,
该函数的变量对象就被压入一个环境栈中,而在函数执行之后,
栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象。
*/
//闭包:内部函数的作用域链仍然保持着对父函数活动对象的引用,称为闭包
// 闭包的作用:
// 1.读取自身函数外部的变量
// 2.让这些外部变量始终保存在内存中
function outer(){
var result=new Array();
for(var i=0;i<2;i++){
//i是outer的局部变量
result[i]=function(){
return i;
}
}
return result;//返回一个函数对象数组
//初始化result.length个关于内部函数的作用域链
}
var fn=outer();
console.log(fn[0]());
console.log(fn[1]());
//2
//2
//function内部的函数执行完毕以后,才会退出循环,进行下一步骤,输出最终结果
//如何让result数组函数返回我们所期待的值
/*
result的活动对象里有一个arguments,
arguments对象是一个参数的集合,是用来保存对象的。
把i当成arguments的参数传进去,这样一调用i就能锁定目标,
找到arguments中的对象
*/
function outer(){
var result=new Array();
for(var i=0;i<2;i++){
//定义一个带参函数
function arg(num){
return num;
}
//把i当成参数传进去
result[i]=arg(i);
}
return result;
}
//var fn = outer();
console.log(outer()[0]);
console.log(outer()[1]);
/*
该方法调用内部函数时,父函数的环境变量还没被销毁,
而且result返回的是一个整数型的数组,而不是一个函数数组。
让arg(num)函数内部再定义一个内部函数。
这样result返回的其实是innerarg()函数
*/
function outer(){
var result=new Array();
for (var i=0;i<2;i++){
//定义一个带参函数
function arg(num){
function innerarg(){
return num;
}
return innerarg;
}
//把i当成参数传进去
result[i]=arg(i);
}
return result;
}
var fn = outer();
console.log(fn[0]());
console.log(fn[1]());
//上述代码中,当调用innerarg()时,
//它会沿作用域链找到夫函数arg()活动对象里的arguments参数num=0;
//函数arg在outer函数内预先被调用执行了,对于这种方法,js有一种简洁的写法
function outer(){
var result = new Array();
for(var i=0;i<2;i++){
//定义一个带参函数
result[i]=function(num){
function innerarg(){
return num;
}
return innerarg;
}(i)//预先执行函数写法,把i当成参数传进去
}
return result;
}
var fn = outer();
console.log(outer()[0]())
console.log(fn[0]());
console.log(fn[1]());
</script>
</body>
</html>
js基础—var全局作用域 ,局部作用域
猜你喜欢
转载自blog.csdn.net/weixin_44158539/article/details/113831138
今日推荐
周排行