原型链和作用域链

Posted kinoko-1009

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原型链和作用域链相关的知识,希望对你有一定的参考价值。

一、原型链:

1.原型对象:

每一个构造函数都有一个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>

 

2.原型链

<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>

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

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

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

以上是关于原型链和作用域链的主要内容,如果未能解决你的问题,请参考以下文章

前端:如何理解 JS 的作用域和作用域链?说说闭包的两个应用场景

JS中的作用域链是在啥时候建立的

作用域链闭包和原型链

预编译作用域链和闭包理解

变量对象作用域链和This

JavaScript中作用域链和闭包