JS中的原型对象与原型链

一、原型对象

我们先来认识一下原型对象吧!

原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。

1. 函数的原型对象

在JavaScript中,我们创建一个函数A,那么浏览器就会在内存中创建一个对象B,而且每个函数都默认会有一个属性 prototype 指向了这个对象(即:prototype的属性的值是这个对象 )。这个对象B就称作是函数A的原型对象,简称函数的原型。这个原型对象B 默认会有一个属性constructor指向了这个函数A ( 意思就是说:constructor属性的值是函数A )。
说这么多,看得懂吗?上图
函数的原型对象

2. 使用构造函数创建对象

当把一个函数作为构造函数,使用new创建对象的时候,那么这个对象就会存在一个默认的不可见的属性,来指向了构造函数的原型对象。这个不可见的属性我们一般用[[prototype]]来表示,只是这个属性没有办法直接访问到。
构造函数的原型对象

  • 创建出的对象虽然使用的是构造函数,但是对象创建出来之后,这个new出来的对象其实已经与Function构造函数没有任何关系了,[[prototype ]]属性指向的是Function构造函数的原型对象。
  • 如果使用new Function()创建多个对象,则多个对象都会同时指向Function构造函数的原型对象。
  • 我们可以手动给这个原型对象添加属性和方法,那么p1,p2,p3…这些对象就会共享这些在原型中添加的属性和方法。
  • 如果我们访问p1中的一个属性name,如果在p1对象中找到,则直接返回。如果p1对象中没有找到,则直接去p1对象的[[prototype]]属性指向的原型对象中查找,如果查找到则返回。(如果原型中也没有找到,则继续向上找原型的原型—原型链。
    后面再讲)。
  • 如果通过p1对象添加了一个属性name,则p1对象来说就屏蔽了原型中的属性name。换句话说:在p1中就没有办法访问到原型的属性name了。
  • 通过p1对象只能读取原型中的属性name的值,而不能修改原型中的属性name的值。 [p1.name] = “李四”;并不是修改了原型中的值,而是在p1对象中给添加了一个属性name。

构造函数的原型对象

  1. 所有的原型对象都是由Object函数对象创建的
  2. Function函数对象由自己Function,Function.proto == Function.prototype
  3. 所有的函数都是由Function函数对象创建
  4. 构造函数创建的对象,对象的proto指向构造函数的prototype
  5. 不是构造函数创建的对象,对象的proto指向Object函数对象的prototype
  6. 对象访问某个属性,如果自己身上有这个属性 优先访问自己的 如果没有再访问原型链上的 沿着原型链依次往上层链找

二、继承-原型链

ECMAScript需要通过原型链来实现继承。

每一个对象都从原型继承属性,直到null结束。
所有的内置构造函数都有一个继承自Object.prototype的原型。

利用下面这个例子来深入一下

var arr1 = new Array(1,2,3);
/* arr1.__proto__
-->Array.prototype的原型__proto__
-->Object.prototype的原型__proto__ 
-->null
形成链,到null结束; */
var date1 = new Date();
/* date1.__proto__
-->Date.prototype的原型__proto__
-->Object.prototype的原型__proto__
-->null
形成链,到null结束;*/

一、构造函数、原型和实例的关系
a,构造函数都有一个属性prototype,这个属性是一个对象,是Object的实例;
b,原型对象prototype里有一个constructor属性,该属性指向原型对象所属的构造函数;
c,实例对象都有一个__proto__属性,该属性指向构造函数的原型对象;
obj.proto===Object.prototype
二、prototype与_proto_的关系
a,prototype是构造函数的属性;
b,__proto__是实例对象的属性;
c,两者都指向同一个对象;

原型链

来道练习题练练手吧

      function Person() {
        this.name = 'qwer';
      }
      var person1 = new Person();

      Person.prototype.w = '这是w属性';
      Function.prototype.q = '这是q属性';
      Object.prototype.e = '这是e属性';

      console.log(person1.w); // person1.__proto__.__proto__.__proto__
      console.log(person1.q); // undefined
      console.log(person1.e);

      console.log(Person.w); // undefined Person.__proto__.__proto__.__proto__
      console.log(Person.q);
      console.log(Person.e);

      console.log(Function.q); // Function.__proto__.__proto__
      console.log(Function.e);

      console.log(Object.q); // Object.__proto__.__proto__
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值