js变量作用域和沿原型链查找变量


    js变量作用域

第一种:没有使用var修饰,定义的是全局变量,在严格模式下该方法不能使用

i = 0;

第二种:使用var修饰,没有定义在函数体内是被认为是window属性,是全局属性,定义在函数体内时是局部属性,仅在当前函数体有效,函数体外无法访问

var i = 0;

第三种:向指定路径添加属性

function fun(){

       fun.i= 0;

};

我们知道,在js中所有对象都是window的属性,所以这种定义方法就相当于window.fun.i=0。通过这种方法定义的变量能够在函数体外被访问。

所以

1.

function fun(){

       vari = 0;

}

alert(fun.i)  //undefined

 

2.function(){

       fun.i= 0;

}

alert(fun.i)  //0

沿原型链查找变量

任意一个function都有8个内置属性

1.  arguments:null

2.  caller:null

3.  length:0

4.  name:"abc"

5.  prototype:{constructorƒ}

6.  __proto__:ƒ ()

7.  [[FunctionLocation]]:question1.html?_ijt=…rgnjroisq25f076v:12

8.  [[Scopes]]:Scopes[1]

其中prototype属性指向该函数的原型,__proto__指向该函数的构造函数

说明Object.prototype.__proto__为什么等于null

        

对于图中对象f1

f1.__proto__=Foo.prototype

f1.__proto__.__proto__=Object.prototype

f1. .__proto__.__proto__.__proto__=null

在原型链查找的过程中,查找f1. .__proto__.__proto__.__proto__就停止了,如果把Object.prototype.__proto__指向Object.prototype或者Function.prototype则会使程序陷入死循环。

 

我们知道js是通过原型链查找的,通过原型链查找是每次都给要查找的变量前面加__proto__,所以说它不是沿着prototype查找的,而是沿着__proto__查找的。

下面说明window是继承子object函数的。

执行console.log(window),在最后一行找到__proto__,可以看到,window的构造函数是f Window(){}window对象的原型是Window.prototype,打开window.__proto__.constructor(即函数f Window()),可以看到f Window(){}的构造函数是f WindowProperties(),可以看到window.__proto__.__proto__WindowProperties.prototype,继续往下可以看到f WindowProperties()的构造函数是ƒ EventTarget()ƒ EventTarget()__proto__Object,即

console.log(window.__proto__.__proto__.__proto__.__proto__)  //Object

由此可以得出,在jswindow对象也是Object的子对象。

 

当你在使用一个没有指定使用者的变量i时,就会默认使用window.i,因此当你把一个变量声明在Object.prototype时,就会顺着原型链window.__proto__.__proto__.__proto__.__proto__.i找到这个变量。

所以对于以下情况

function fun(){

fun.i = 9;

alert(i);
}

输出为undefined。因为这个变量被定义在window.fun.i,在window的原型链中没有这个变量。

js中所有对象都是window的对象,所以对于当你输入fun.i调用这个对象时默认是window.fun.i

对于一个稍微复杂一点的情况:

var k = {u:3}

var l = {o:2}

l.__proto__ = k

function abc() {}

abc.prototype.__proto__ = l

abc()

alert(abc.u)  //undefined
其中abc.u等同于window.abc.u,会在abc构造函数(f Function())这条原型链中查找,而这个变量被定义在了abc的原型这条原型链当中,所以输出undefined,把代码最后一句改成abc.prototype.u就可以输出3了。
也就是说通过abc.u可以访问定义在function原型中的属性,即
Function.u = 9;
function abc() {};
alert(abc.u)  //9
需要注意并不是所有的对象都是继承Object,可以通过修改属性来使得它不继承任何对象。
      K={
            __proto__:null
      }

但是所有对象都一定使window的属性或方法。 上面第一个图片来自不知道哪个网友的,很有用的个图片,既然不知道是谁的图,我们可以感谢祖国

 

阅读更多
文章标签: js javascript
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

js变量作用域和沿原型链查找变量

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭