显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

 显式原型与隐式原型

显式原型:prototype             

 隐式原型:__proto__

1. 每个函数function都有一个prototype,即显式原型(属性)
2. 每个实例对象都有一个__proto__,可称为隐式原型(属性)

3. 对象的隐式原型的值为其对应构造函数的显式原型的值

4. 总结:

  * 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象

  * 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值

  *Object.prototype的__proto__属性指向null。

区别:

__proto__是每个对象都有的一个属性,而prototype是函数才会有(函数也有__proto__)的属性。

__proto__指向的是当前对象的原型对象,而prototype指向它的构造函数的原型对象。

作用:

1、肯定是为了继承!

2、prototype用来实现基于原型的继承与属性的共享。

3、__proto__就构成了我们常说的原型链 访问构造方法中的显示原型,同样用于实现基于原型的继承。

在js中万物皆对象,方法(Function)是对象,方法的原型(Function.prototype)是对象,对象具有属性(__proto__)称为隐式原型,对象的隐式原型指向构造该对象的构造函数的显式原型


[javascript]  view plain  copy
  1. //定义构造函数  
  2.   function Fn() {   // 内部语句: this.prototype = {}  
  3.   
  4.   }  
  5.   // 1. 每个函数function都有一个prototype,即显式原型属性, 默认指向一个空的Object对象  
  6.   console.log(Fn.prototype)  
  7.   // 2. 每个实例对象都有一个__proto__,可称为隐式原型  
  8.   //创建实例对象  
  9.   var fn = new Fn()  // 内部语句: this.__proto__ = Fn.prototype  
  10.   console.log(fn.__proto__)  
  11.   // 3. 对象的隐式原型的值为其对应构造函数的显式原型的值  
  12.   console.log(Fn.prototype===fn.__proto__) // true  
  13.   //给原型添加方法  
  14.   Fn.prototype.test = function () {  
  15.     console.log('test()')  
  16.   }  
  17.   //通过实例调用原型的方法  
  18.   fn.test()

  •     构造函数的显示原型的隐式原型:
  1. 内建对象(built-in object):比如Array(),Array.prototype.__proto__指向什么?Array.prototype也是一个对象,对象就是由 Object() 这个构造函数创建的,因此Array.prototype.__proto__ === Object.prototype //true,或者也可以这么理解,所有的内建对象都是由Object()创建而来。
  • 自定义对象
1. 默认情况下:
function Foo(){}
var foo = new Foo()
Foo.prototype.__proto__ === Object.prototype //true 理由同上
Foo.prototype===foo._proto_ //true
2. 其他情况: 
(1)
 function Bar(){}
//这时我们想让Foo继承Bar
Foo.prototype = new Bar()
 Foo.prototype.__proto__ === Bar.prototype //true
(2)
//我们不想让Foo继承谁,但是我们要自己重新定义Foo.prototype
复制代码
Foo.prototype = {
  a:10,
  b:-10
}
//这种方式就是用了对象字面量的方式来创建一个对象,根据前文所述 
Foo.prototype.__proto__ === Object.prototype
复制代码

: 以上两种情况都等于完全重写了Foo.prototype,所以Foo.prototype.constructor也跟着改变了,于是乎constructor这个属性和原来的构造函数Foo()也就切断了联系。

  • 构造函数的隐式原型

既然是构造函数那么它就是Function()的实例,因此也就指向Function.prototype,比如 Object.__proto__ === Function.prototype



手绘原型链





原型链是什么

实现继承主要依赖原型链。 

什么是原型对象。我们知道每个构造函数一旦创建都有prototype指针指向它的原型对象(构造函数.prototype)。而原型对象(构造函数.prototype)会默认生成一个constructor指针又指向构造函数。在创建实例时,实例有一个内部属性[[prototype]]指向该原型对象。原型对象内创建的所有方法会被所有实例共享。 

原型是什么?

在JavaScript中原型是一个prototype对象,用于表示类型之间的关系。

什么是原型链。

JavaScript万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。

原型链就是创建一个构造函数,它会默认生成一个prototype属性并指向原型对象。使用下一个构造函数的原型对象作为这个构造函数的实例。即 nextFuction.prototype = new thisFuction(); 

在下下一个构造函数的原型对象 = new nextFuction。这样下去就会构成一条实例与原型之间的链条,这就是原型链。


为什么要有原型链

构造函数的所有实例都可以访问构造函数原型中的方法和属性。

也就是把共有的东西统一存放到一个共享空间。这样可以避免相同函数重复声明,减少空间占用,节省内存。

实现继承,子类继承父类的方法和变量;

原型上可以定义一些方法和变量;

以这个原型建立的对象,可以使用原型方法和变量,从而实现继承。


猜你喜欢

转载自blog.csdn.net/weixin_40387601/article/details/80327955