JS原型链

  emmmmm,我为了写这篇博客,看了不少别人写的有关于原型链的介绍,我发现了最重要的点

  1. 所有的类天生自带一个属性prototype[原型],它是一个对象,【既然是一个对象,浏览器会默认开辟一个堆内存】
  2. 在prototype【堆内存】当中,天生自带一个属性constructor【构造函数】,每个构造函数(constructor)都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针,而实例(instance)都包含一个指向原型对象的内部指针.
  3. 所有的对象天生自带一个属性__proto__【原型链】,他指向当前所属类的原型
  4. ※  “潜规则” : 如果想要引用对象(实例instance)的某个属性,会先在对象内部寻找该属性,知道找不到,然后再在该对象的原型(instance.prototype)里去找这个属性,层层向上直到null,mull没有原型,并作为原型链的最后一个环节

例子详解:

   

achieve(){
			function Father(){
				this.property = true;
			}
			console.dir(Father)
			Father.prototype.getFatherValue = function(){
				return this.property;
			}
			function Son(){
				this.sonProperty = false;
			}
			//继承 Father
			Son.prototype = new Father();                    //Son.prototype被重写,导致Son.prototype.constructor也一同被重写
			Son.prototype.getSonVaule = function(){
				return this.sonProperty;
			}
			var instance = new Son();
			console.log(instance)
			console.log(instance.sonProperty)		 //false
			console.log(instance.getFatherValue())           //true
			alert(instance.getFatherValue());                //true
			// instance实例通过原型链找到了Father原型中的getFatherValue方法.

		},

  因为不是很懂,我给每个地方都打印了一下,详解见下图~

  

  再次打印~~~

  

  儿子Son同理 然后就是儿子继承了自己的父亲,在儿子继承父亲class的时候,子类的__proto__ 属性指向父类,子类的原型__proto__,也总是指向父类的prototype属性,ES6中的class继承多了一个Object.setPrototypeOf(Child, Parent) 的步骤,即 Child.__proto__ = Parent

  但是呢,儿子在继承父类的时候,自己的son.prototype被重写,导致了son.prototype.constructor也被重写了

  

最后打印结果

  

  这基本上就是走了一个流程图 instance实例通过原型链找到了Father原型中的getFatherValue方法.

  总结如下: 

    var 对象 = new 函数()                                                              var instance = new Son()

    对象.__proto__ === 对象的构造函数.prototype                       instance.__proto__  === Son.prototype

    Son 的原型对象是 Function 即 Son是Function的实例  那么   Son.__proto__ == Function.prototype

  __proto__属性:在这个万物皆对象的年代,每一个对象都有属性__proto__,这个对象会指向对象的原型

  prototype属性:万物皆对象,万物中当然也包括函数,函数也是一个对象,而且函数除了拥有__proto__属性外,另外还有一个prototype属性,这个函数的prototype属性指向了一个对象,而这个对象是窎远构造函数而创建的实例的原型,他一般生活在我们的继承中

  在我认为的两者之间的区别,显而易见的就是  prototype是函数的内置属性,_ proto_ 是对象的内置属性,另外附上一个规则

    1..所有的引用类型(数组、对象、函数)都具有对象特性,即可自由扩展属性(除了“null”)

    2..所有的引用类型(数组、对象、函数)都有一个 _proto_ 属性(隐式原型属性),属性值是一个普通的对象

    3..所有的函数,都有一个 prototype(显式原型)属性,属性值也是一个普通的对象

    4..所有的引用类型(数组、对象、函数), _proto_ 属性值(隐式原型属性)指向它的构造函数的“prototype”属性值,当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的 prototype(显式原型))中寻找

  this 是个啥?

    1.谁最终调用函数,this指向谁。
      ①this指向的永远只可能是对象!!!
      ②this指向谁永远不取决于this写在哪,而是取决于函数在哪调用
      ③this指向的对象,称之为函数的上下文context,也叫函数的调用者

    2.this指向的规律(与函数调用的方式息息相关):
      this指向的情况,取决于函数调用方式有哪些,
      ①通过函数名()直接调用:this指向window    =>>>>> function func(){ }
      ②通过对象.函数名()调用的:this指向这个对象    =>>>>>func();
      ③函数通过数组的一个元素,通过数组下标调用的,this指向这个数组    var arr=[func,1,2,3];arr[0]();
      ④函数作为window内置函数的回调函数调用时,this指向window如setTimeout setInterval 等    setTimeout(func,1000);
      ⑤函数作为构造函数用new关键字调用时,this指向新new出的对象。  var obj = new func();

posted on 2019-06-17 21:27  你还喜欢现在吗?  阅读(347)  评论(2编辑  收藏  举报