JavaScript-原型理解

我是每天被自己菜醒的跳跳,嗯~就很菜!

我们所创建的每一个函数,解析器都会向函数添加一个属性,prototype,这个属性对应着一个对象,这个对象就是我们所谓的原型对象。

如果函数作为普通函数调用prototype没有任何作用的。

当函数以构造函数的形式调用时,他所创建的实例对象中都会有一个隐含属性,指向该构造函数的原型,我们可以通过proto来访问属性。

 

		<script type="text/javascript">
			var a = function(){
					console.log(this.name+"构造函数")
					console.log(this)
					}
			var stuProty ={
				like:function(){
					console.log(this.name+"构造函数")
					console.log(this)
					},
				b:function(){
					console.log("吃饭睡觉打豆豆")
				}
			}
			//构造函数
			function student(name,age){
				this.name = name;
				this.age = age;
				//创建一个全局变量name和age,这里的name指向的是window
				// this.like = a
				}
				student.prototype = stuProty
				console.log(student)
			
			// 利用构造函数自定义对象
			var stu1 = new student('狗儿',12)
			var stu2 = new student("狗三",22)
			stu1.like()
			stu2.like()
			
			
		</script>

上述代码的原型如下图

此处有两个原型的原因是,1处原型在代码中student.prototype = stuProty有这一句,给他加了原型,然后1处的原型里面的2原型指向student。

这样一个原型里面有另一个原型,就构成了一个原型链,

 

值得注意的是如果对象的属性和原型里的函数重名了,自己属性的优先级会高于原型上的优先级,如下图

stu1和stu2使用的是同一个构造函数创建出来的实例对象,他们两个都有一个共同的原型函数like

在1处,给stu1加了一个属性like=12345;-->这样不会修改原型中同名like函数的样子,只是给stu1加了一个属性,在2处可以看出并没有影响。

在3处在进行调用stu1的原型函数like时报错,但是在4处可以调用stu1的属性like,说明在stu1中同名的属性比原型中的函数优先级要高。

在5处就可以看出,stu1的属性和原型是共存的。

如果想调用stu1原型上like函数,使用stu1__proto__.like()来调用,如上图,但是此处的this是发生了改变,指向了_porto__也就是构造函数,不是指向的stu1,所以报了undefined。

在2处使用.call来改变this的指向,将原型从指向构造函数改为指向stu1.

当然尽量不要重名啦!

 

1.原型对象相当于一个公共区域,所有同一个类的实例都可以访问到这个原型对象,我可以将对象中共有的内容,设置到原型对象中去。

2.使用原型对象在以后创建构造函数的时候,可以将对象共有的属性和方法,同意添加到构造函数的原型对象中去,这样就不用了分别为每一个对象添加,不会占内存,也不会影响到全局作用域。

3.使用in来检查对象中是否含有某个属性的时候,如果对象的属性中没有但是原型中有,也会返回true。可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性。

4.原型链,原型对象也是对象,所以他也有原型,当我们使用或者访问一个对象的属性或方法时:

  • 他会先在对象自身去寻找,有则直接使用
  • 没有则会原型中去寻找,找到了则直接使用
  • 再没有则去原型的原型中去找,有则直接使用,一直找到Object对象的原型
  • 还没的话就返回null

从4处我们可以看处,想要改写Object的toString方法,只需要在实例自身上写一个相同名字的toString方法,来改写我们原型上的方法,来达到我们的效果。需要注意的是不要直接去改Object的方法,否则的话全局的都改了,别人用就GG了。

 

 

本人是个菜逼,理解有错误的地方,欢迎指正。记录下学习笔记。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章