变量的作用域

变量的作用域:

作用:起作用。

域:范围,区域。

1,变量的生命周期。

2,哪里可以访问变量。

----------------作用域-----------

1,全局作用域  全局都可以访问的变量的区域

2,局部作用域:主要就是函数作用,理解为:函数体内部的执行环境。

 

不存在的变量或函数会报错;不存在的属性或方法,返回undefined;

 

javascript 没有块级作用域:

比如

{   ......   }  //在这个花括号里面的变量就叫块级作用域,但JS中没有块级作用。

比如:

if(){......}   for(){.....)等等:

<script>
if (true) {
var a=0;//属于全局变量,因为JS不存在块级作用域,即:{}花括号之间的作用域,其他语言会有
}
for (var i = 0; i < elements.length; i++) {
var b=1;//属于全局变量,因为JS不存在块级作用域,即:{}花括号之间的作用域,其他语言会有
}
</script>

----------------------------------------

<script>
function fn(){
var x=y=1;
console.log(x);//返回 1
console.log(y);//返回 1
}
// console.log(x);//报错,因为x是局部变量,不能再函数体以外进行访问。
fn();//如果不执行该方法,则输出下面y就会报错: y is undefined
console.log(y);//返回 1
</script>

---------js没有块级作用,所以变量都是全局作用域------------

script type="text/javascript">
if (true) {
var name="xm";  //在js中没有块级作用域,所以,这里的name是全局变量。
};
document.write(name);//输出:xm
</script>

--------------------

script type="text/javascript">
if (true) {
var a.name="xm"; //这里的对象a没有声明,所以会出现uncaught SystaxError的错误。
};
document.write(a.name);// 虽然js不存在块级作用,但是每个对象必须声明。变量可以直接使用,如:name等于 var name。
</script>

-----------------

因为不用var声明的变量是全局变量,y是全局变量,可以输出;x是局部变量,因此输出x会报错。

<script type="text/javascript">
function fn(){
var x=y=1;//这里的y用var声明,所以是全局变量。
}
fn();
document.write(y);
document.write(x);
</script>

因为不用var声明的变量是全局变量,y是全局变量,可以输出;x是局部变量,因此输出x会报错。

---------------

在JS中,主要是全局变量和,函数变量(局部变量)

说白了,下面的两个a完全不同,第一个是全局变量,函数内的是局部变量。

<script type="text/javascript">
var a="xm"; //这里的a 是全局变量
function fn(){
var a="xh";  //这里的a 是局部变量,在函数中重新声明了。
document.write(a); //这里读取的是局部变量,所以a="xh"。
}
fn();
document.write(a); //这里读取的是全局变量,而不是局部变量,所以a="xm"。
</script>

-------

下一个例子完全相反:

-------

说白了,下面只有一个全局变量a。

<script type="text/javascript">
var a="xm";
function fn(){
a="xh";  //在函数内没有用var声明变量,说明是全局变量,a的值被改为 "xh"。
document.write(a); //全局变量 a="xh"。
}
fn();
document.write(a);//全局变量a在函数内被修改为"xh",所以这里的a="xh"。
</script>

 ===============

全局作用域的  变量对象   window:

<script>
var a=70;
function add(){
return a+10;
}
add();//返回80;
console.log(window.a===a);//返回 true
console.log(window.add===add);//返回 true
</script>

-------------------------

局部作用域的 变量对象 :

<script>
var a=70;
function add(){
  return a+10;

  var b=10;
  function fn(){

    var c=20;
    return a+b+c+20;
  }
}
</script>

解析:

1,全局作用域变量对象

  window.a===a

  window.add===add

2,add函数的局部作用变量对象,是看不见摸不着的,假如局部变量的变量对象是:add

  add.b===b

  add.fn===fn

3,fn函数的局部作用变量对象,是看不见摸不着的,假如局部变量的变量对象是:fn

  fn.c===c

三个作用域就连成了一个作用域链:

作用域都是从内层向外层查找属性值。

如查找 fn.c 的值的查找顺序----fn局部作用域----add局部作用域-----window全局作用域,取最近存在的值,即:fn.c=20,如果不存在,返回undefined

如查找 fn.a 的值的查找顺序----fn局部作用域----add局部作用域-----window全局作用域,fn.a=window.a=70。

如查找 add.a 的值的查找顺序 ---add.a局部作用域 -----window全局作用域,add.a=window.a=70

如查找 add.c 的值的查找顺序----add.a局部作用-----window全局作用域,不存在,所以add.c 返回:undefined,这里add.c!==fn.c,只可以向外查找,不能向内查找。

所以,局部变量一定比全局变量效率高,内层变量一定比外层变量效率高。

============

通过 with(obj) 来延长作用域链,但是这个很鸡肋,降低效率,还有其他一切问题,不推荐使用,了解即可,如下代码:

<script>
/*
注意比较以下全局变量对象和局部变量对象的属性和方法:

全局变量对象window的属性及方法:
1,window.person对象
2,window.score属性*/
  var person={};
  var person.name="xm";
  var person.sex="male";
  var score=80;

/*局部变量对象person
1,person.name 等价于修改了上面的window.person.name
2,person.sex 等价于修改了上面的window.person.sex
3,person.score 等价于widow.score*/
with(person){
  name="xh";//全局属性中已经定了变量对象window的属性person对象中name的属性,所以这里只是重新赋值。
  sex="female";//全局属性中已经定了变量对象window的属性person对象中sex的属性,所以这里只是重新赋值。
  score=90; //因为person不存在该属性,全局属性中已经定了person的属性,所以继承了window.score的值,并且修改了。
}
</script>

============

<script type="text/javascript">

//以下 person未定义的变量 报错

document.write(person || person="xm");
document.write(window.person || window.person="xm");
</script>

不存在的变量或函数会报错;不存在的属性或方法,返回undefined;||是短路操作,形如a||b,如果a的值转换成布尔值是true的话,a||b等于a;如果a的值转换成布尔值是false的话,a||b等于b。

--------------------

<body>
<button>1</button>
<button>2</button>
<button>3</button>
<script type="text/javascript">
var btns=document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
btns[i].οnclick=function(){
alert(i);
}
}
</script>
</body>

以上是:这里是由于先绑定,后触发,给每个按钮绑定事件,但是在触发的时候i已经是循环完之后,所以i的值一直都是3。

 

转载于:https://www.cnblogs.com/Knowledge-is-infinite/p/10614788.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值