对象和作用域

一直以来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对象和作用域的关系,但实际上通过上面的例子可以知道,它们并没有关系,都是个人见解,有误后续会修改
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值