首页 > 代码库 > js作用域的几个问题

js作用域的几个问题

按照《权威指南》的说法,全局的变量作用域是全局性的,在js代码中,他处处都有定义。而在函数之内声明的变量,就只有在函数体内有定义了。函数的参数也是局部变量,他们只在函数体内部有定义。在函数体内部,局部变量的优先级比同名的全局变量高。如果给一个局部变量或函数的参数声明的名字与全局变量的名字相同,那么就有效地隐藏了这个全局变量。

  js没有块级作用域,,函数中声明的所有变量,无论在哪里,如for ,if等,在整个函数中他们都是有定义的。这个也叫变量提升,作用域都是在函数中。

1,对象内部的作用

?
1
2
3
4
5
6
var a =  10;
var AAA = function (){
    console.log(this.a);
}
var b  = {a:2,bbb:AAA};
b.bbb();

   最后输出的是2,this指向的自己的对象。this需要牢记的是 他是自己的对象的范围。点之前的作用域,是b所以bbb()执行的是b的作用域。

2,对象共享的问题

?
1
2
3
4
5
6
7
8
var cat ={};
cat.mouse = function(){var b="1111"};
var dog = cat;
console.log(dog);
console.log(dog.mouse);
dog.mouse = function(){var b="2222"};
dog.hat="b";
console.log(cat)

  

Object {mouse: function}
hat: "b"
mouse: function (){var b="2222"}
__proto__: Object


function (){var b="1111"} 


Object {mouse: function, hat: "b"}
hat: "b"
mouse: function (){var b="2222"}
__proto__: Object

对象赋值后,指向了同一个对象,及时改变的是第二个对象,第一个对象也跟着变。conosle.log 看到是最后结果了。引用同一个对象,大家一起变。

3,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var test=function(){
    var a=1;
    setTimeout(function(){
        console.log(a);
        a=2;
    },1000);
    a=3;
    setTimeout(function(){
        console.log(a);
        a=4;
    },2000);
  
};
test(); 

结果是3,2;

共享内存。setTimeout等异步,是取现在当时的a的值。执行第一个setTimeout的时候,a=3,已经执行了。全局的对象,同一个引用。外部变量不仅可以被访问到也可以被修改。

4,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var foo=10;
var a=1;
var  main = function (){
//a=10;
console.log(a);
a=20;
console.log(this.foo);
this.foo=foo;
console.log(this.foo);
foo=1000;
console.log("111111111111");
}
var s=main();
var d=new main();

 结果是: 

1

10

10

111111111111

 

20

undefined

1000

111111111111

不加new 都是全局的,this指向的全局变量。所以第一个就取得是全局的值。

第二个加new 了,this.foo指向的是自己,没有定义于是就报undefined。外面a foo等是全局变量,main(),执行后,a已经变成20了,foo也变成1000了,所以值发生变化了,因为全局变量。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var foo=10;
var a=1;
var  main = function (){
//a=10;
console.log(a);
a=20;
console.log(this.foo);
this.foo=foo;
console.log(this.foo);
foo=1000;
console.log("111111111111");
}
//var s=main();
var d=new main(); 

如果不执行第一个,结果发生变化。可以发现其实是全局变量的修改。

undefined

10

111111111111

 

5、

?
1
2
3
4
5
6
7
8
9
10
11
12
var a = 10;
var b = function(){
    console.log(this.a);
}
 
var c = function(){
    this.a = 123;
    var d = b;
    d();
}
 
var e = new c;<br>console.log(window.a);
?
1
2
3
4
5
6
7
8
9
var a = 10;
var c = function(){
    this.a = 123;
    var d = function(){
      console.log(this.a);
    };
    d();
}
var e = new c; 

结果是10。 window.a其实就是全局的那个a。this指的是在一个函数内部调用它的上下文关系,单独的一个函数了。var d单独的一个函数,他的this.a指向的是全局的了,没有作用域,就是全局了。

?
1
2
3
4
5
6
7
8
9
10
11
12
var a = 10;
var b = function(){
  console.log(this.a);
}
 
var c = function(){
  this.a = 123;
  this.d = b;
  this.d();
}
 
var e = new c;

  结果是123,如果this.d(),写成d(),会报错 d is not defined。 this.d 将d的后面的this变成了c这个函数了。点执行方法,作用域是点之前的。

 

?
1
2
3
4
5
6
7
8
9
var a = 10;
var c = function(){
    this.a = 123;
    this.d = function(){
        console.log(a);
    };
    this.d();
}
var e = new c;

  结果是10。

 

参考:http://www.cnblogs.com/bennman/archive/2013/09/08/3309024.html

在 JavaScript 中,上下文对象就是 this 指针,即被调用函数所处的环境。上下文对象 的作用是在一个函数内部引用调用它的对象本身。


在 JavaScript 中,本质上,函数类型的变量是指向这个函数实体的一个引用,在引用之 间赋值不会对对象产生复制行为。我们可以通过函数的任何一个引用调用这个函数,不同之处仅仅在于上下文。
仔细观察上面的例子,使用不同的引用来调用同一个函数时,this 指针永远是这个引用所属的对象.

 函数作用域的嵌套关系是定义时决定的,而不是调用时决定的,也就 是说,JavaScript 的作用域是静态作用域,又叫词法作用域,这是因为作用域的嵌套关系可 以在语法分析时确定,而不必等到运行时确定