JavaScript 原型 原型链 详解

一、原型

1.每个函数,都有一个内置属性,叫做prototype(原型)(prototype是一个对象)

2.如果一个对象是通过new产生的,那么这个对象将有缺省的属性,__ proto__,这个属性指向函数的原型

 

 原型的用处:用来让所有的构造函数生成的对象可以共享属性和方法,构造函数产生的对象获得,prototype的属性和方法,在构造函数原型上的方法和属性都是共享的

 function Dog(name, age){  //构造函数
     this.name = name;
     this.age = age;
 }
 Dog.prototype.eat = function(food){// 在构造函数的原型上面增加方法
     console.log(food);
 }
 var dog1 = new Dog('doubao', 3); //实例
 var dog2 = new Dog('wawa', 4);

//下面为共用一个方法
 dog1.eat('apple');//运行结果为 apple
 dog2.eat('rice'); //运行结果为 rice
 console.log(dog1.eat === dog2.eat);//运行结果为true

 //下面为共用一个属性
 Dog.prototype.headNumber = '1';
 console.log(dog1.headNumber);//运行结果为1
 console.log(dog2.headNumber); //运行结果为1

原型的方法,既可以访问原型中的其他的方法和属性,也可以访问实例上自己的属性  

 // 原型的方法,既可以访问原型中的其他的方法和属性,也可以访问实例上自己的属性
  Dog.prototype.eat2 = function(){
     this.eat('meat');    //访问原型中其他的方法 
     console.log(this.headNumber); //访问原型中其他的属性  
     console.log(this.age);//访问实例中自己的属性 
 }
 dog1.eat2(); //运行结果为  meat
 						   1
 						   3

 原型的性质:

1.直接在实例上增加方法或者属性,是属于实例本身的,不会影响构造函数的原型

2.当运行需要实例的某种方法或者属性时,首先在实例本身上寻找方法或者属性,如果找不到去原型上找,如果还找不到,返回undefined

 dog1.headNumber = '2' //直接在实例上增加与在原型上相同的属性,但属性内容同
 console.log(dog1.headNumber);//运行结果为2 首先在实例本身上寻找方法或者属性
 console.log(dog2.headNumber);//运行结果为1 在实例dog1增加的属性不会影响到构造函数的原型

 

二、原型链

原型链顾名思义是一条链式的结构,首先先来看一个简单的例子

 

用代码来对上述图片进行实现

//创建构造函数
function A1(){
	this.m = 'mm';
}
//用Object创建一个对象obj,并给obj增加属性和方法			
var obj = new Object;
obj.n = 'nn';
obj.f = function(){
	console.log('123')
}
//用obj替换A1.prototype			
A1.prototype = obj;
obj.constructor = A1;
//创建实例
var a1 = new A1();
console.log(a1.n);//运行结果为 nn
a1.f();			  //运行结果为 hello

 由此我们可见,我们可以用一个实例对象来替换一个构造函数的prototype,并且此实例对象原本的属性和方法,也能被构造函数所创造出的实例所用。

构造原型链的步骤

1.从Object开始,每一层底层的构造函数构造出实例,作为上一层构造函数的原型对象

2.构造好后,通过对象的 _proto__,可以一直追溯到null\Object,这个链表称为原型链

我们再来看一个三层继承的例子

 

 用代码来对上述图片进行实现

//创建obj对象实例,并在obj上增加属性
var obj = new Object();
obj.objM = 'objMM';
//创建A1构造函数
function A1(){
	this.g = 'gg'
}
//使obj成为A1.prototype
A1.prototype = obj;
obj.constructor = A1;
//通过构造函数A1创建对象实例a1,并在a1上增加属性
var a1 = new A1();
a1.a1M = 'a1MM';
//创建A2构造函数
function A2(){
	this.h = 'hh'
}
//使a1成为A2.prototype	
A2.prototype = a1;
a1.constructor = A2;
//通过构造函数A2创建对象实例a2,并在a2上增加属性		
var a2 = new A2();
a2.a2M = 'a2MM';
//创建A3构造函数			
function A3(){
	this.i = 'ii'
}
//使a2成为A3.prototype			
A3.prototype = a2;
a2.constructor = A3;
//通过构造函数A3创建对象实例a3			
var a3 = new A3();
//通过实例对象a3来依次调用原型链各层的属性			
console.log(a3.a2M);//运行结果为a2MM
console.log(a3.a1M);//运行结果为a1MM
console.log(a3.objM);//运行结果为objMM

原型链的性质:

1.所有挂在原型链对象上的属性和方法,能够被所有派生实例共享

2.如果访问一个示例的属性或者方法,先从对象本身找起,如果发现没有,会沿着原型链由近至远寻找

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值