原型链和作用域链
一、原型链:
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>
三、原型链和作用域链的区别:
原型链:原型链作用在构造函数上,原型链操作的是构造函数的属性:实例属性和原型属性;
作用域链:作用域链作用域普通函数上,操作的是全局变量和局部变量。