js中作用域和上下文等问题分析

来源:互联网 发布:机械制图网络课程 编辑:程序博客网 时间:2024/05/29 13:58

博客

作用域、上下文、闭包、原型、继承

作用域:

作用域简单点说就是作用的区间,作用域又分为全局作用域和函数作用域,顾名思义全局作用域就是包含着共用的对象或者属性,而函数作用域是某个函数特有的作用域。

更重要的是,作用域在文件被执行的时候就已经创建好了,后面不会再更改。

如下这个例子就能说明:

 

再来看看打印的结果:

 

按照我们原有的思路,一个for循环i值本应该是逐渐加一变大,打印的值也应该是从04,但是它却直接打印出来一个五。

这就涉及到作用域的问题了,第一张图可以看见,整个代码可以分为两个部分,全局作用域包括定义的数组对象和for循环,函数作用域包括定义的studnt函数。需要打印i的时候,先在离它最近的student函数作用域内去寻找,发现没有就去上一级的全局作用域去寻找,发现有i,但是全局作用域里面的i早已经完成for循环变成了5,因此打印出来的为5

可以看出来,作用域在刚被创建的时候就已经确定了,然而为什么函数作用域里面没有i却能够去全局作用域中去寻找呢,这就涉及到上下文的问题了。

 

上下文

上下文我个人觉得是作用域的衍生,作用域在创建的时候就生成了,相关的对象和属性存放在作用域内,在函数被调用的时候会产生上下文,而相关的对象和属性也会随之存放进上下文,函数调用结束上下文也随之消失。

如下例子:

 

再来看看打印结果:

 

全局作用域里面有两个对象,分别为number类型的a和     namestudent函数作用域里面也有number类型的啊,teacher函数作用域里面没有任何对象。

teacher函数被调用的时候生成teacher上下文,里面不包含要打印的namea,于是往上级函数去调用,studen上下文包含a,数值为8;在往上级寻找name,在全局作用域里面找到name,为张三,于是打印出来为“张三8”。

由此可以看出来上下文的层级关系,在低级函数上下文里面没有相关的对象时,向上级上下文去寻找,且以最相近的上下文为准。

闭包

我们都知道闭包的创建条件有两个,第一个是要有函数内部要返回一个函数,第二个就是要有返回的函数使用到了外部函数的自由变量。

使用闭包可以很好的避免在引入多个js文件时发生对象冲突,也可以很好的减少不必要函数的调用次数,执行速度更加快速。

原型

所有的对象的最终原型为object,所有的函数的最终原型为Function。每个对象都会有一个prototype属性也会有一个__proto__属性,prototype属性指向的是自身的构造器。

要讲述的东西太多,个人也不是非常理解,尽我所能。

如下例子:

 

 

再来试试不去定义stuname属性会打印什么:

 

 

由此可见,新建一个student函数的对象stu是一个新的函数,它的__proto__属性指向的是student函数的构造器,所以第二次打印的是构造器中的内容“李四湖北”;而当定义了stu自身的name属性后,打印的即为“张三湖北”。

这也涉及到作用域和上下文的问题,本身的上下文没有name属性时,就往上级上下文找,就是student函数构造器的上下文。

原型还有更多内容,如下图就是所有原型大致的关系:

其中stu1stu2是创建函数对象。

 

 

继承

我想在想到继承就基本的就是继承方法,最多的也是继承object对象有的方法。

本身新建的对象是不含有方法的,但是能够调用很多方法,原因在于都继承了顶级父类object的方法。

如下例子:

 

 

打印结果为:

 

obj数组本身是没有hasOwnProperty方法的,是通过继承构造器里面方法,从而调用的。

 

 

 

从中也可以看出来obj.__proto__指向的是object对象,因此方法也是继承于object中存在的方法。

 

从作用域、上下文、闭包、原型、继承可以看出来,它们都是相互关联的,共生共灭的关系。

原创粉丝点击