摘要:一直以来的原型链和作用域链非常困扰我,其中夹杂着问题更是让问题雪上加霜,并不是说原型链或者说作用域链有多难理解,而是经常混乱了概念,下面记录一下思考过程,希望对自己或是他人都有帮助。
一直以来JavaScript的原型链和作用域链非常困扰我,其中夹杂着this问题更是让问题雪上加霜,并不是说原型链或者说作用域链有多难理解,而是经常混乱了概念,下面记录一下思考过程,希望对自己或是他人都有帮助。
var maybe="maybe" function ObjectMake (){ var maybe = "hello"; this.getmaybe = function(){ return maybe; } } var b = new ObjectMake(); var c = b.getmaybe(); //hello
作用域(scope)是针对函数而言的,每个函数在执行的时候都会分配作用域链,上面例子是一个典型的工厂模式,其中对于ObjectMake函数而言,其作用域链[[scope]]是scope_0(Windows)+scope_1(ObjectMake),对于getmaybe函数而言,其作用域是scope_0(Windows)+scope_1(ObjectMake)+scope_2(getmaybe),在scope0和scope1都存在maybe变量的时候,scope1优先于scope0,所以变量c的值是hello。
下面这种情况呢:
var maybe="maybe"; var getmaybe = function(){ return maybe; } function ObjectMake (){ var maybe = "hello"; this.getmaybe = getmaybe; } var b = new ObjectMake(); var c = b.getmaybe(); //maybe 根据作用域链分析可以得出:对于getmaybe函数而言,其作用域链[[scope]]是scope_0(Windows)+scope_1(getmaybe),对于对于ObjectMake函数而言,其作用域链[[scope]]是scope_0(Windows)+scope_1(ObjectMake),所以当运行b.getmaybe时getmaybe查找作用域只能在cope_0(Windows)中发现maybe变量,故c的值为maybe。 有人可能会提出一个问题,为什么getmaybe函数作用域链没有包含scope_1(ObjectMake),因为JavaScript是词法作用域,简而言之,就是函数的作用域链只和函数在哪里定义有关系,和函数在哪里运行没有关系,上面getmaybe定义在Windows中,所以其作用域链中只存在两个:Windows和它自己。 明白了这个道理,下面这个例子又让我晕了很久: var maybe = "maybe"; var show = { maybe:"hello", getmaybe:function(){ return maybe; } } var d = show.getmaybe();//maybe 按照之前的说法,getmaybe定义在对象show对象当中,为何d的值不是maybe?让我们还是从之前的分析作用域链开始,函数getmaybe定义在对象show中,其作用域链为:scope_0(Windows)+scope_(getmaybe),scope作用域代表获取执行环境的地址,目前JavaScript的执行环境有:1)全局执行环境、2)Eval函数执行环境、3)普通函数执行环境,可知show对象不是一个执行环境,函数的scope无法将它推入作用域链中,所以d的值为maybe。 下面我们再看一个例子: var maybe = "maybe"; var show = { maybe:"hello", getmaybe:function(){ return this.maybe; } } var d = show.getmaybe();//hello 上面在getmaybe函数中加上this指针后,终于返回了hello了,this指针在JavaScript中是一个非常重要但是又常常会误导人的概念,在一般的OOP(面向对象的语言中),一般都有this这个概念,比如c++的this,Python的self等等。this代表对象实例的地址,在JavaScript中,对象都是实例,不存在C++中的class概念,而this都是动态绑定的(可以用apply()或是call()等函数来改变),show.getmaybe()将getmaybe函数的this指针绑定了show对象,有些时候this指针会被偷偷的替换掉,这个时候可能我们都不知道,关于this指针,下次有时间再写一篇作为理解之用。 这篇文章主要是关于JavaScript对象和作用域的关系,但实际上通过上面的例子可以知道,它们并没有关系,都是个人见解,有误后续会修改。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86564.html
摘要:示例当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。每一个运行期上下文都和一个作用域链关联。此时,作用域链中函数的所有局部变量所在的作用域对象会被推后,访问代价变高了。 作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。 作用域链 函数对象有一个内部属性[...
摘要:所以,全局执行环境的变量对象始终都是作用域链中的最后一个对象。讲到这里,可能你已经对执行环境执行环境对象变量对象作用域作用域链的理解已经他们之间的关系有了一个较清晰的认识。 JavaScript中的执行环境、作用域、作用域链、闭包一直是一个非常有意思的话题,很多博主和大神都分享过相关的文章。这些知识点不仅比较抽象,不易理解,更重要的是与这些知识点相关的问题在面试中高频出现。之前我也看过...
摘要:每一个运行期上下文都和一个作用域链关联。这个对象将被推入作用域链的头部,这意味着函数的所有局部变量现在处于第二个作用域链对象中,因此访问代价更高了。在代码块内部,函数的所有局部变量将会被放在第二个作用域链对象中。 参考: Javascript作用域原理 理解 JavaScript 作用域和作用域链 JavaScript 作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数...
摘要:作用域与作用域链每个函数都有自己的执行环境。这是初步了解作用域,如想更深入了解作用域,请看下面链接作用域原理作用域链由一道题图解的作用域或者看权威指南和高级程序设计 本文是我学习JavaScript作用域整理的笔记,如有不对,请多指出。 作用域 一个变量的作用域是程序源代码中定义这个变量的区域。 而在ES5中只分为全局作用域和函数作用域,也就是说for,if,while等语句是不会创建...
摘要:当函数被调用的时候,作用域链就会包含多个作用域对象。但是当函数要访问时,并没有找到,于是沿着作用域链向上查找,在的作用域找到了对应的标示符,就会修改的值。 JS JavaScript闭包和作用域 闭包 JavaScript高级程序设计中对闭包的定义:闭包是指有权访问另外一个函数作用域中变量的函数。 从概念上,闭包有两个特点: 函数 能访问另外一个函数的作用域中的变量 在ES6之前,...
摘要:变量对象也是有父作用域的。作用域链的顶端是全局对象。当函数被调用的时候,作用域链就会包含多个作用域对象。当函数要访问时,没有找到,于是沿着作用域链向上查找,在的作用域找到了对应的标示符,就会修改的值。 一、概要 对于闭包的定义(红宝书P178):闭包就是指有权访问另外一个函数的作用域中的变量的函数。 关键点: 1、闭包是一个函数 2、能够访问另外一个函数作用域中的变量 二、闭包特性 对...
阅读 3640·2021-10-13 09:40
阅读 3118·2021-10-09 09:53
阅读 3529·2021-09-26 09:46
阅读 1811·2021-09-08 09:36
阅读 4218·2021-09-02 09:46
阅读 1293·2019-08-30 15:54
阅读 3050·2019-08-30 15:44
阅读 1005·2019-08-30 11:06