zoukankan      html  css  js  c++  java
  • Javascript原型及闭包

     

    一.函数与对象的爱恨情仇

             一切皆为对象,但并不是所有的都是对象,其中undefined, number, string, boolean)属于简单的值类型,不是对象。剩下的几种情况——函数、数组、对象、null或者new一个对象,都是对象,他们都是引用类型

     

     1.对象是属性的集合(important!!!!!)

         对象里面的一切都是属性,只有属性,没有方法--方法也是一种属性,因为它的属性表示为键值对的形式。关于函数与数组对象定义属性是以其他形式定义的。

                               

                             

    反正一切(引用类型)是对象,对象是属性的集合

    2.对象都是函数创建的,函数也是对象,有一种鸡生蛋蛋生鸡的逻辑(别急后面会理清这种关系的)

    ---关于对象都是函数创建的如:

                      

    以上代码的本质  

                    

     Object Array 都是函数:

    console.log(typeof (Object));  // function

    console.log(typeof (Array));  // function

    ---函数也是对象,也是属性的集合

        每个函数都有一个prototype属性(这就是为什么函数是对象了,因为它里面已经事先有一个属性了,而对象又是属性的集合,逻辑是不是很对!没毛病!)指向该函数的原型对象(既然是对象,也是属性的集合!!!),只要是对象就有一个__proto__ 属性指向构造函数

    3.关于对象:

          i本人理解如果用构造函数的方法创造对象,形如就是先创建一个模型,其中Fn函数里定义了很多属性,既然Fn是函数,那么Fn就有prototype属性指向该函数的原型对象。该函数的原型对象你可以自己在里面定义一些属性,该函数的原型对象里有一个constructor属性指向该构造函数。如果你要想要继承我这些属性,可以通过new关键字,new出一个新的对象。

        ii只要new出f1新对象了,那么f1对象就会继承函数里的所有属性,既然f1是对象,那么就有__proto__属性指向构造函数的原型即

                           

    iii上文说过Object 和 Array 都是函数,因为要创造此类型对象要new一个出来,说明他们也是构造函数,形如function Object(){}和function Array(){}.。并且他们已经是系统创建好了。

    iiii这里先讲一下new的机制为下面的原型链做下铺垫。

                                 

                                     

    (这里我觉得new时,不仅把构造函数的原型对象赋给创造出来的对象,而且还继承了构造函数里定义的属性)

    iiiii这里还有一个逻辑问题,关于前文说的对象都是函数创建的,函数也是对象,那么函数是怎么出来的,不可能是石头里蹦出来的吧!且看如下代码:

     

    4.原型及原型链就以图解形式

             每每看到这些图,我都有一种杀人的冲动,冲动是魔鬼,理解了以后才会明白很多问题:

        

           (这里解释一下构造函数,所谓构造函数就是用来new对象的函数。其实严格来说,所有的函数都可以new一个对象,但是有些函数的定义是为了new一个对象,而有些函数则不是。另外注意,构造函数的函数名第一个字母大写(规则约定)例如:Object、Array、Function等)

         function fn(){};

         var test = new fn();

      

    这里new的机制就是把test.__proto__=fn.prototype,实现原型继承。要想使用一个对象的属性,首先在自身查找这个属性,如果没有找到就在原型链上查找,直到为空为止。

    5.this的指向问题

       i在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。

       ii 构造函数情况241行中的this在没有new时this指的是window,当new以后指向函数函数本身(也是对象)。

          

    iii函数作为对象一个属性时

     1.如果函数作为对象的一个属性时,并且作为对象的一个属性被调用,函数中的this指向该对象。

     

    2.注意,如果fn函数不作为obj的一个属性被调用,会是什么结果呢?

       

    iiii特殊情况

       

    Javascript没有块(这里的块指的是{})级作用域的概念,javascript除了全局作用域之外,只有函数可以创建作用域。所以这里的f()还是一个普通的函数,是在全局作用域下运行的。

    二.作用域及闭包的问题

    1.且看下面例题:

    两句话特别重要:1.变量声明提前,但不会赋值2.函数声明优与变量声明

    alert(a)

    a();var a=3; function a(){

        alert(10)

    }   

    alert(a)

    a=6;

    a();  

     

    ------------分割线------------------

     

    alert(a)

    a();var a=3;var a=function(){

        alert(10)

    }   

    alert(a)

    a=6;

    a();

    第一题等价于:

               

      第二题等价于:   

          

    2.寻找作用域问题

              

    这里x的值时,就需要到另一个作用域中取,有人说过要到父作用域中取,其实有时候这种解释会产生歧义,要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”

    上面描述的只是跨一步作用域去寻找。

    如果跨了一步,还没找到呢?——接着跨!——一直跨到全局作用域为止。要是在全局作用域中都没有找到,那就是真的没有了。

    这个一步一步“跨”的路线,我们称之为——作用域链

    我们拿文字总结一下取自由变量时的这个“作用域链”过程:(假设a是自由量)

    第一步,现在当前作用域查找a,如果有则获取并结束。如果没有则继续;

    第二步,如果当前作用域是全局作用域,则证明a未定义,结束;否则继续;

    第三步,(不是全局作用域,那就是函数作用域)将创建该函数的作用域作为当前作用域;

    第四步,跳转到第一步。

    3.闭包

      只要知道应用的两个情况就可以了:

    第一:函数作为返回值

              

    第二:函数作为参数传递

               

    这里也用到跨作用域了,在执行到11行时,寻找max在自己的作用域找不到时,就跨到全局作用域去找。

     

    本文参考:http://www.cnblogs.com/wangfupeng1988/p/3977924.html

    感想:本文是在2017年11月下旬面试总结下来的,个人感觉学知识,学技术,不能知其然,不知其所以然,不能抱着侥幸的心理。

     

        

  • 相关阅读:
    6、深入理解计算机系统笔记:存储器层次结构,存储技术(1)
    流程图【占无内容】
    程序的三种基本控制架构【只有提纲】
    Console算法[for]穷举法:百钱买百鸡
    Logic算法(狼羊白菜)
    Console算法continue与break的区别?
    Console算法[for]简单画图
    Console算法[for]输出等腰三角形
    Console算法[for]国王与老人的六十四格
    Console算法[for]素数
  • 原文地址:https://www.cnblogs.com/youtian/p/7859609.html
Copyright © 2011-2022 走看看