精华内容
下载资源
问答
  • 作用域链和原型链

    2020-02-13 13:25:37
    原型链作用域链 区别: 作用域是对于变量而言,原型链是对于对象的属性。 作用域链顶层是window,原型链顶层是Object。 联系:从链表开头寻找,直到找到为止。 二、作用域链 作用域 作用域就是变量与函数的可...

    一.原型链与作用域链
    区别:

    1. 作用域是对于变量而言,原型链是对于对象的属性。
    2. 作用域链顶层是window,原型链顶层是Object。

    联系:从链表开头寻找,直到找到为止。

    二、作用域链

    1. 作用域
      作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。作用域分为全局作用域和局部作用域
      全局作用域:任何地方都能访问到的对象拥有全局作用域。
      局部作用域:局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以在一些地方会把这种作用域成为函数作用域。
    2. 作用域链
      作用域链,即当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。
      var a = 10;
      function fun(){
      console.log(a);
      var a = 1;
      var b = 20;
      b++;
      function fun1(){
      console.log(b);
      b += 6;
      function fun2(){
      console.log(b);
      console.log(a);
      }
      }
      console.log(a);
      }
      在这里插入图片描述
      1、首先,开始执行前,创建执行环境(数组):ECS
      向执行环境栈中压入第一个默认的函数main(),创建全局作用域对象Window,全局做预编译GO,函数的隐藏属性scope记录执行期上下包括自己的所属作用域的对象。如上图
      2、执行开始,在执行环境中压入新的函数,创建一个活动的AO,保存函数中的局部变量,当自己的AO中没有该变量,可以通AO中的parent(scope)中去寻找。
      3、执行结束,执行环境中的的本次函数出栈,同时创建的活动对象AO消失。

    三、原型链

    1. 什么是原型
      每个构造函数都有一个prototype属性,这个属性指向一个对象,即原型对象。
      原型对象默认拥有一个constructor属性,指向指向它的那个构造函数(也就是说构造函数和原型对象是互相指向的关系)。
    2. 什么是原型链
      由于__proto__任何对象都具有的属性,js中一切都是对象,所以一条由__proto__形成的链条,顶端为null,即原型链。

    function Student(sname, sage){
    this.sname = sname;
    this.sage = sage;
    }
    Student.prototype.intr = function(){
    console.log(I'm ${this.sname},I'm ${this.sage});
    }
    var lilie = new Student(“Li Lei”, 12);
    var hmm = new Student(“Han Meimei”, 12);

    其原型链图如下
    在这里插入图片描述
    Student.proto ==>Function.prototype
    Function.prototype.constructor ==> function Function(){}
    Function.prototype.proto ==>Object.prototype
    Function.prototype.proto ==>Object.prototype

    展开全文
  • 深入理解js原型链和作用域链,了解作用域链和原型链的区别一、原型链二、作用域链三、原型链和作用域链的区别:总结 一、原型链 每一个构造函数都有一个prototype属性,这个属性就叫原型对象。 每一个构造函数new...

    深入理解js原型链和作用域链,了解作用域链和原型链的区别

    一、原型链

    每一个构造函数都有一个prototype属性,这个属性就叫原型对象。

    每一个构造函数new出来的对象都有一个–proto–属性,这个属性指向原型对象。

    在这里插入图片描述

    <script>
       function Car(){
               //实例属性:
              //this.produce = ‘chevrolet‘,
              this.price = 8800000;
           }
              //原型属性:
           Car.prototype.produce = "BMW";
           var chevrolet = new Car();
           console.log(chevrolet.produce,chevrolet.price);//BMW 8800000  
           console.log(chevrolet==Car.prototype);//false;  构造函数new出来的对象和构造函数的原型对象不是同一个对象。
           console.log(chevrolet.produce==Car.prototype.produce);//true;
           /*构造函数new出来的对象和构造函数的原型对象不是同一个对象,为什么构造函数new出来的对象能获取到构造函数原型对象的
           属性:因为每一个构造函数new出来的对象都有一个--protot--原型链,该原型链可以把new出来的对象和原型对象连接在一起。
           */
    </script>
    
    <script>
    //    function Car(){
    //        //实例属性:
    //       this.produce = ‘chevrolet‘,
    //       this.price = 8800000;
    //    }
    //    var chevrolet = new Car();
    //    console.log(chevrolet.produce,chevrolet.price);//chevrolet 8800000
    
    
    //    function Car(){
    //        //实例属性:
    //      // this.produce = ‘chevrolet‘,
    //       this.price = 8800000;
    //    }
    //    //原型属性:
    //    Car.prototype.produce = "BMW";//prototype相对于构造函数而言,写法:构造函数名.prototype.属性
    //    var chevrolet = new Car();
    //    console.log(chevrolet.produce,chevrolet.price);//BMW 8800000
    
    //    function Car(){
    //        //实例属性:
    //       this.produce = ‘chevrolet‘,
    //       this.price = 8800000;
    //    }
    //    //原型属性:
    //    Car.prototype.produce = "BMW";
    //    var chevrolet = new Car();
    //    console.log(chevrolet.produce,chevrolet.price);//chevrolet 8800000  原型链的解析过程:先找实例属性,再找原型属性。
    
       function Car(){
           //实例属性:
          //this.produce = ‘chevrolet‘,
          this.price = 8800000;
       }
       //原型属性:
      // Car.prototype.produce = "BMW";
       var chevrolet = new Car();
       Object.prototype.produce = ‘Audi‘;
       console.log(chevrolet.produce,chevrolet.price);//Audi 8800000  
       //原型链的解析过程:先找实例属性,再找原型属性,若实例属性和原型属性都不存在,则找Object的原型属性。
    
    </script>
    

    二、作用域链

    全局作用域、局部作用域。

    <script>
       var num = 10;
       function fn(num){
           num = 20;
       }
       fn();
       console.log(num);//10
       //向上查找,在函数体内找到同样的变量,操作的就是局部,否则是全局。
       //题解:1.找var,fn-->2.逐行解析代码:全局变量num;遇到函数跳过;调用函数,解析函数体:变量num向上查找,在函数体内
       //找到形参num,所以此处num是局部变量,因此输出结果为全局变量num=10。
    </script>
    
    <script>
       var num = 10;
       function fn(){
           num = 20;
       }
       fn();
       console.log(num);//20
       //题解:1.找var,fn——>2.逐行解析代码:全局变量num;遇到函数跳过;调用函数,解析函数体:变量num向上查找,在函数体内
       //没有找到num,继续在全局范围内找,找到全局变量num,并将num=20赋值于全局变量,因此输出结果为全局变量num=20。
    </script>
    
    <script>
        var num = 10;
       function fn(){
         var num = 20;//在函数体内部使用var明确定义的变量是私有变量。
       }
       fn();
       console.log(num);//10
       //题解:函数调用后,函数体内的变量会被销毁,所以输出结果10。
    </script>
    

    三、原型链和作用域链的区别:

    原型链:原型链作用在构造函数上,原型链操作的是构造函数的属性:实例属性和原型属性;

    作用域链:作用域链作用域普通函数上,操作的是全局变量和局部变量。

    总结

    good afternoon
    展开全文
  • JavaScript作用域链和原型链 作用域链 作用域 ​ 作用域,是指变量的生命周期(一个变量在哪个范围内保持一定的值),在JavaScript中,作用域分为以下几种:全局作用域、函数作用域、块级作用域、动态作用域。 ...

    JavaScript作用域链和原型链

    1. 作用域链
    • 作用域

      ​ 作用域,是指变量的生命周期(一个变量在哪个范围内保持一定的值),在JavaScript中,作用域分为以下几种:全局作用域函数作用域块级作用域动态作用域

      • 全局作用域

        全局变量存在于整个程序中,程序中的任何函数、任何方法均可访问全局变量,但全局变量不能滥用,所以操作或使用未生命的变量,JS会默认生命此变量为全局变量。

      • 函数作用域

        函数作用域内,对外是封闭的,外层无法直接访问内部变量,内部可访问外层的变量

      • 块级作用域(ES6)

        使用功能let关键字声明,可形成块级作用域

      • 动态作用域

        this引用会存在动态作用域

      • 执行上下文

        ​ 执行上下文即当前代码的执行环境,可以描述成是一个包含变量对象、活动对象、作用域链和this的数据结构。

      • 作用域链

        ​ JS所有函数都有它的执行环境(执行上下文),当它执行的时候会被压入环境栈,如果执行完毕,会将当前环境弹出,执行环境中有函数作用域中定义的变量和其他信息,作用域链最顶端是当前执行环境,下一个是上层环境,一直到Windows对象。举个例子:

        function Outer(){
            var out = 123;
            Inner();
            function Inner(){
                var inner = 456;
                console.log(out,inner);   //123,456
            }
        }
        Outer();
        

        Inner内部既可以访问Inner的作用域,也可以访问Outer的作用域。因此,当多个作用域互相嵌套时,就形成了作用域。词法作用域在查找标识符的时候会就近查找,从当前作用域向外逐层查找,当抵达最外层作用域依然没有找到,则停止查找。如果是RHS则会抛出错误,如果是LHS则会在全局范围内声明该变量。

      • 闭包

        定义:函数在定义的作用域以外的地方被调用,闭包使得函数可以继续访问定义时的作用域。举个例子:

        function fn(){
            var temp = 123;
            function func(){
                console.log(temp);
            }
            return func;
        }
        var func = fn();
        func();      //123
        

        func则是有一个闭包函数,使得全局范围可以访问fn函数作用域内部的变量temp,且函数执行完后,fn对象的活动变量不会被销毁,因为fn返回的函数func的作用域链还保持着fn的活动变量,因此JavaScript的垃圾回收机制不会回收fn活动变量。综上所述,闭包会引起内存泄漏,尽量不要使用闭包。

      • 垃圾回收机制

        JS的垃圾回收机制分为两种,分别为标记清除和引用计数

        • 标记清除:垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后它会去掉环境中的变量以及环境中的变量引用的变量的标记,如果此时还存在有标记的变量就视为准备删除的变量,因为环境中的变量无法访问到这些变量,最后垃圾收集器完成内存清理,销毁这些变量并回收内存。
        • 引用计数:记录每一个值被引用的次数,当声明一个变量并将一个引用类型值赋给该变量时,该变量的引用次数加一,如果一个值又被赋给另外一个变量,则该值的引用次数减一,当这个值的引用次数为0时,就说明没有办法再访问这个值了,就可以回收该变量的空间,当垃圾收集器下次运行时,它会释放这个值占用的内存。
    1. 原型链
    • 原型

      ​ 所有的函数都有一个特殊的属性:prototype,prototype属性是一个指针,指向原型对象,原型对象中的方法和属性都可以被函数的实例所共享。通过构造函数创建的对象实例都可以共享构造函数的原型的方法。举个例子:

      var Person = function(name){
          this.name = name;
      }
      Person.prototype.sayName = function(){
          console.log(name);
      }
      var person = new Person('aa');
      person.sayName();  //aa
      

      上述例子中对象personPerson构造函数创建的实例,通过new操作符调用构造函数时主要执行以下几个步骤:

      • 创建新的对象,并将函数的this指向新创建的对象
      • 执行函数
      • 返回新创建的对象

      通过构造函数创建的对象,内部有一个_proto_指针指向构造函数的原型对象

      构造函数的原型对象有一个constructor属性,指向构造函数

      • 原型链

        当执行以下代码时:

        person.toString();
        

        首先会在person实例中查找toString属性,发现不存在该属性;会转到Person原型对象去找toString属性,仍然不存在;接着到Person原型对象的_proto_指向的Object原型对象中找,终于找到,然后执行toString方法。这样整个串起来就是一条原型链,原型链的顶端为null

      prototype:构造函数具有的属性,指向调用构造函数而创建的实例的原型

      _proto_:指向对象的原型

      constructor:原型对象的属性,指向原型对象对应的构造函数

      在这里插入图片描述

    1. 作用域链和原型链的比较
    • 作用域链是主要的作用是查找标识符,从当前作用域沿着作用域链依次查找,如找到会停止查找,否则会继续查找,直到尾部;尾部依然没有找到的情况分为两种,如果RHS,会抛出未找到变量的错误,如果是LHS,会在查找的最外层声明变量。
    • 原型链是用于查找引用类型的属性,沿着作用域链依次向上查找,如果找到该属性会停止查找并作出相应的操作,否则会沿着原型链依次查找到结尾,尾部依然没有找到的情况分为两种,如果是RHS,会返回undefined,如果是LHS,会在该对象实例中声明变量,不会去查找原型链。
    展开全文
  • 最在在学习前端一些技术,首先就看了js红宝书,觉得这本书确实讲的很细致,值得看,接下来就是根据我看的我自己理解的对作用域链和原型链的总结。作用域链:提到作用域链,大家应该都会想到一个名词执行环境,执行...

    最在在学习前端一些技术,首先就看了js红宝书,觉得这本书确实讲的很细致,值得看,接下来就是根据我看的我自己理解的对作用域链和原型链的总结。

    作用域链:提到作用域链,大家应该都会想到一个名词执行环境,执行环境就是代码执行时的作用域,与执行环境相对应的一个就是变量对象,每一个执行环境都对应一个变量对象,变量对象是存储该执行环境里函数和变量的一个对象。当代码执行的时候,会根据变量对象生成一个作用域链。作用域链的前端总是当前执行环境的变量对象。作用域链的下一个变量对象是包含环境,而再下一个变量对象是包含环境的包含环境,……最后一个变量对象总是全局执行环境对应的变量对象。

    变量对象中保存的是该变量对象对应的执行环境中所定义的变量和函数,每一个变量对象中都有一个argument属性,该属性是一个类数组对象。

    作用域链有个特点,作用域链只能支持向上搜索,而不支持向下搜索,就是当前执行环境中可以访问其包含环境中的变量和函数,而不可以访问其被包含环境中的变量和函数。

    而原型链是在继承的时候用的一个很重要的概念。其基本思想就是通过原型让一个引用类型来使用另一个引用类型的属性和函数。

    下面我通过一个简单的例子来说明使用原型链实现继承。

    function A(){

        this.property=true;

    }

    A.prototype.getAValue=function (){

        return this.property;

    }

    function B(){

        this.myproperty=false;

    }

    B.prototype=new A();

    B.prototype.getBValue=function (){

        return this.myproperty;

    }


    var instance = new B();

    console.log(instance.property);

    console.log(instance.getAValue());//true

    加粗部分就是B继承A。

    而他的原理是这样的

    因为每一个对象中都有prototype这个属性,这个属性是一个对象,该对象指向的是该属性所在构造函数的原型对象。A.prototype指向的是A的原型对象,而B.prototype指向的是B的原型对象。B.prototype=new A()。实际上是将B的原型对象中的[[Prototype]]的指向改变为A的原型对象。


    展开全文
  • 由此逐层衍生,逐层嵌套的作用域,称之为作用域链。拥有以下的特性。 1 外层作用域无法调用内层作用域的变量。比如全局作用域无法调用局部作用域声明的变量或常量。 function func(){ var foo =...
  • js作用域链和原型链

    2020-02-16 09:35:10
    作用域链 如果要理解作用域链就要先理解作用域,所以要先明白作用域 一、作用域 作用域就是变量与函数的可访问范围 即作用域控制着变量与函数的可见性生命周期 二、作用域分为全局作用域局部作用域 全局作用域...
  • 作用域链:函数执行会形成一个私有的作用域,形参在当前私有作用域中声明的变量都是私有变量,当前的私有作用域有自我保护机制,私有变量中遇到一个非私有的变量,则向它的上级作用域找,如果还不是上级作用域私有...
  • 作用域链的概念:  要理解ES中作用域链,首先要从理解执行环境开始。ES中代码执行都是在一个具体的执行环境中进行的,每个执行环境有一个与之关联的变量对象,该变量中包含着在这个执行环境中可以访问的变量函数...
  • 毕业也整整一年了,看着很多学弟都毕业了,忽然心中颇有感慨,时间一去不复还呀。记得从去年这个时候接触到...为了防止之后自己又开始模糊,所以自己来总结一下JavaScript中关于 作用域链和原型链的知识,并将二者...
  • 作用域链:针对变量 原型链: 针对构造函数(对于对象的属性,方法) 形式不同 作用域链: 作用域的特点就是,先在自己的变量范围中查找,如果找不到,就会沿着作用域往上找。如: var a = 1; function b(){ var a...
  • 每一段javascript代码(全局代码或函数)都有一个与之关联的作用域链(scope chain)。...在不包含嵌套的函数体内,作用域链上有两个对象,第一个是定义函数参数局部变量的对象,第二个是全局对象。在一个嵌套的...
  • 那么就说说原型链和作用域链的问题,刚学习的时候,这两者是分开学的,并没有 在这两者之间有困扰,但是当回过头来综合学习的时候,却在这两者之间产生了困惑, 后来经过学习,发现原来这两者完全属于不同的范围,...
  • 作用域链 作用域是针对变量的,比如我们创建了一个函数a,函数A里面又包含了一个函数b,那么现在就有三个作用域: 全局作用域==&gt;函数a作用域==&gt;函数b作用域 作用域的特点就是,先在自己的变量范围中...
  • 什么是作用域
  • 一、作用域链 Javascript引擎在执行环境对象中访问作用域内的变量,查找的顺序叫做作用域链 1.作用域链示例: 每次调用,regular_joe在作用域内都有定义 //在全局作用域里,设置regular_joe var regular_joe ...
  • 作用域是针对变量的,比如我们创建了一个函数,函数里面又包含了一个函数,那么现在就有三个作用域  函数2作用域==>函数1作用域==>全局作用域 作用域的特点就是,先在自己的变量范围中查找,如果找不到,就...
  • 每一个javascript对象(null除外)都有一个prototype属性(这个属性引用了一个对象,即原型对象),都从...通过关键字new构造函数调用创建的对象的原型就是构造函数的prototype属性的值。因此,使用{}通过new Obje...
  • 为了防止之后自己又开始模糊,所以自己来总结一下JavaScript中关于 作用域链和原型链的知识,并将二者相比较看待进一步加深理解。以下内容都纯属于自己的理解,有不对的地方欢迎指正。 作用域链 作用域  首先...
  • 方法:当方法的返回值是一个对象时,这个对象还可以再调用它的方法。这种方法调用序列中,每次调用的结果都是另外一个表达式的组成部分。 比如:基于jQuery库,我们通常会写类似如下代码: $(this).next()....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,006
精华内容 402
关键字:

作用域链和原型链