浅析原型和原型链

        昨天看对原型概念有了一点点的兴趣,虽说了解的不是很透彻,但是还是多多少少有一点收获的,就自己的一些学习到的东西做一个小小的总结。主要是结合了课本、网上资源和一些视频来学习的。

        原型涉及到了原型、原型链和构造函数。而且在每个博客的讲解中都涉及到了构造函数的内容,那就先从构造函数的概念和作用谈起。

    构造函数

        构造函数我们应该都很清楚了,在学习C#的时候接触过这个概念。在JS的学习中:构造函数的特点:

    a:构造函数的首字母必须大写,用来区分于普通函数

    b:内部使用的this对象,来指向即将要生成的实例对象

    c:使用New来生成实例对象

例如:

//构造函数
function Person(name,age){
     this.name = name;    
     this.age = age;   
     this.sayHello = function(){   
         console.log(this.name +"say hello");
    }
}

var boy = new Person("bella",23);    
boy.sayHello(); // bella say hello

构造函数的缺点:

    所有的实例对象都可以继承构造器函数中的属性和方法。但是,同一个对象实例之间,无法共享属性

    解决思路:

      a:所有实例都会通过原型链引用到prototype

      b:prototype相当于特定类型所有实例都可以访问到的一个公共容器

      c:那么我们就将重复的东西放到公共容易就好了

如下显示:

function Person(name,age){
    this.name = name;
    this.age = age;
    this.sayHello = function(){
        console.log(this.name + "say hello");
    }
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name);  //bella
console.log(boy.name);   //alex
console.log(girl.sayHello === boy.sayHello);  //false

    原型

        prototype(原型):是function对象的一个熟悉性,定义了构造函数制造出的对象的公共祖先(公共属性和方法)通过构造函数产生对象,可以继承改变原型的属性和方法。原型也是对象。

      __proto__(隐士原型):每个对象的__proto__属性指向自身构造函数的prototype;

        constructor(构造器):返回对创建此对象的数组函数的作用。

prototype属性的作用

  js中每个数据类型都是对象,除了null 和 undefined,而每个对象都是继承自一个原型对象,只有null除外,它没有自己的原型对象,最终的Object的原型为null

function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.propotype.sayHello = function(){
    console.log(this.name + "say hello");
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name);  //bella
console.log(boy.name);   //alex
console.log(girl.sayHello === boy.sayHello);  //true

     

     由上图可以看出,prototype是构造函数的属性,而consructor则是构造函数的prototype属性所指向的那个对象,也就是说constuctor是原型对象的属性。

  constructor属性是定义在原型对象上面,意味着也可以被实例对象继承。

 

  •        如果有原型,那么就一定有函数。每一个对象有一个属性叫__proto__;这个属性就是对象的原型。对象有原型,那么原型也是对象,原型也有原型。
  • 所有的函数是对象,继承自Function.prototype
  •  Function.prototype是对象,继承自Object.prototype
  • Object.prototype是对象,继承自null
  • obj是对象,继承自Object.prototype
  • Function是对象,继承自Function.prototype
  • Function是函数,继承自Function.prototype

         这就涉及到了原型链。

      原型链

        首先看一段代码:

<!DOCTYPE html>
<html> 
	<head>
		<title></title>
		<style type="text/css">
			
		</style>
		<script type="text/javascript">
			var o = {}; //{ name:"我是祖宗"};
			
			var f1 = function() {
				// this.name = "我是亚当";
			};
			f1.prototype=o;
			var foo1 = new f1();
			
			var f2 = function() {
				// this.name = "夏娃";
			}
			var foo2 = new f2();
			foo2.__proto__ = foo1;
			
			var f3 = function() {
				// this.name = "我是人类";
			};
			f3.prototype = foo2;
			
			var foo3 = new f3();
			alert(foo3.name);
		</script>
	</head>
	<body>
	</body>
</html>

        上面代码的运行结果:

1)当所有的this.name,都没有注释的话:运行结果----》我是人类

2)当f3的this.name 注释掉,运行结果-----》我是夏娃

3)当f2和f3中的this.name注释,运行结果是-----》我是亚当

4)当f1,f2,f3中的this.name注释,运行结果----》我是祖宗,

5)当全部被注释掉,运行结果是undefined;

   js成员的访问规则

  • o.方法()
  • 首先在o当前这个类型中寻找该成员的定义,如果存在该成员的定义
  • 那么就直接使用改成员
  • 如果该成员不再当前类型中,就访问其原型(原型链中的上一级)
  • 以此类推,直到null位置

        上图中的原型链:

原型链
对象 __proto__ prototype

constructor

foo Foo.prototype --- ---
obj Object.prototype --- ---
Foo Function.prototype Foo.prototype  
Foo.prototype Object.prototype --- Foo
Function Function.prototype Function.prototype  
Function.Prototype Object.prototype --- Function
obj Object.prototype --- ---
Object Function.prototype Object.prototype ---
Object.prototype null --- Object

参考链接:

https://www.cnblogs.com/thonrt/p/5900510.html

https://www.cnblogs.com/wjyz/p/10219106.html

发布了137 篇原创文章 · 获赞 28 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43267344/article/details/105112601