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