原型和闭包

本文深入解析JavaScript中的原型链机制,包括对象的_propto_属性,函数的prototype属性,以及如何通过原型链查找属性。同时,文章详细介绍了执行上下文环境的生成过程,作用域的定义及其在代码执行中的作用,以及this指针在不同情况下的指向规则。
摘要由CSDN通过智能技术生成

原型及原型链

    每个对象都有一个_propto_(隐式原型),指向创建该对象的函数的proptotype(原型)。

    Object.prototype的_proto_指向的是null。

    函数也是对象,函数也有_proto_,函数是Function创建的。因此,Object._proto_指向的时Function.prototype。(Object也是一个函数)

    既然Function也是一种对象,那么Function._proto_指向的是创建该对象(Function)的函数(Function)的Function.prototype。而Function.prototype._proto_指向的是Object.prototype。以上逻辑可自行分析。

    当访问一个对象的属性时,会先从基本属性中找,如果没有,则沿着_proto_这条链向上找,这就是原型链。

执行上下文环境及作用域

    执行上下文(或执行上下文环境)在准备阶段会完成以下工作:

    1.变量、函数表达式--变量声明,默认赋值为undefined

    2.this--赋值

    3.函数声明--赋值;

 

    javascript在执行一段代码前,会进行这些准备工作来生成执行上下文,这个代码段其实分三种情况:全局代码、函数体、eval代码。其中eval代码接收的也是一段文本形式的代码,例如:eval('alert(qwe)');函数体时代码段是因为函数在创建时,本质上是new Function(...)得来的,需要传入一个文本形式的参数作为函数体。

    全局代码的上下文环境数据内容为:

    1.普通变量(包括函数表达式)  ---声明

    2.函数声明    ---赋值

    3.this    ---赋值

    如果代码段是函数体,则再次基础上附加:

    1.参数    ---赋值

    2.arguments   ---赋值

    3.自由变量的取值作用域  ----赋值

    要给上下文环境下一个通俗定义:在执行代码前,把将要用到的所有变量都事先拿出来,有的直接赋值了,有的先用undefined占个空。

this指针

    1.构造函数

    所谓构造函数,就是可以用来new对象的函数。注意,构造函数的第一个字母大写。如果函数作为构造函数使用,那么其中的this代表它即将new出来的对象,例如:function AA(){this.name='wewe'};var aa=new AA();aa();如果直接调用,this则指向windows,例如:AA()。

    2.函数作为对象的一个属性

    如果函数作为对象的一个属性,且作为对象的一个属性被调用时,this指向该对象,例如:var  obj={fax:function(){this.name='dsad'}};obj.fax();

    如果函数被赋值到另一个变量中,并没有作为对象的属性被调用,this指向window,例如:var func=obj.fax; func();

    3.函数用call或apply调用

    当一个函数被call或apply调用时,this指向传入的对象,例如:var  obj={name:'wewe',code:'dasda'}; var func=function (){console.log(this)};   func.call(obj);

    4.全局&调用普通函数

    在全局环境下,this永远指向window。普通函数在调用时,this也指向window,例如:var func=function(){console.log(this)};func();

下面例子中的情况需要注意:

    var  obj={

        name:'sddsd',

        func:function(){

                    function f(){

                        console(this);//这里this依然指向window

                    }

                    f();

                }    

    };

    obj.func();

关于this的补充内容

    在函数的原型链中,this代表的是当前函数对象的值,例如:function Func(){this.name='name';};  var func=new Func();   Func.prototype.getName=function (){console.log(this.name)};     func.getName();

作用域

    javascript中除了全局作用域,只有函数可以创建作用域,因此,在声明变量时,全局代码要在代码前端声明,函数中要在函数体一开始就声明好,且建议用单‘var’的形式声明变量。

    作用域有上下级的关系,上下级关系的确定是看函数是在哪个作用域下创建的。而作用域最大的好处就是隔离变量,不同作用域下的同名变量不会有冲突。作用域是在函数定义时就已经确定了,而不是在函数调用时。

    作用域是一个抽象的概念,类似于地盘,其中没有变量。要通过作用域对应的执行上下文来获取变量的值。作用域中变量的值是在执行过程中产生并确定的,而作用域则是在函数创建时确定的。如果要查找一个作用域下某个变量的值,需要到该作用域对应的执行上下文环境中寻找。

    自由变量需要到创建(非调用)该函数的那个作用域中取,这就是所谓的静态作用域。

    作用域链中取自由变量值的过程:

    1.在当前作用域下查找,有责获取并结束,无则下一步;

    2.若当前作用域为全局作用域,则证明该自由变量未定义,结束;否则继续;

    3.将创建该函数的作用域作为当前作用域;

    4.跳转到第一步;

 

使用闭包会增加内容开销(因为自由变量的存在,可能会导致一些存放自由变量的上下文环境无法及时销毁)

转载于:https://my.oschina.net/u/3992644/blog/2353503

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值