JavaScript原型及原型链

原型
什么是原型?
  • 实例对象中有一个属性:__ proto__,是对象,叫原型,但不是标准的属性,是浏览器使用的,有的浏览器如谷歌和火狐支持,但是IE8不支持
  • 构造函数中有一个属性:prototype,也是对象,也叫原型,是标准的属性,是程序员使用过的,所有的浏览器都支持
  • 原型:__ proto__或者prototype(两者指向的是同一个对象),都是原型对象
原型的作用

通过原型来添加方法(把方法添加到构造函数的原型对象中,构造函数的所有实例对象就都有这个方法,并且是同一个方法),解决数据共享的问题,节省内存空间

构造函数、实例对象和原型对象之间的关系

通过构造函数创建的实例对象,构造函数中有一个prototype属性指向的是其原型对象,原型对象中有一个constructor属性指向的是其所在的构造函数自身,实例对象中有一个__ proto__属性指向的是其构造函数的原型对象,构造函数的原型对象(prototype)的方法可以被其实例对象直接访问

(注意一点:实例对象可以调用其构造函数的原型对象的属性和方法,但不是说实例对象就有了这些属性和方法 —— console.dir(对象)的结果中是没有的,这些属性和方法在其下划线原型中)

原型的简单语法

指的是将需要添加给构造函数的原型的属性和方法组成对象直接赋给构造函数的原型对象

Person.prototype = { // 这种方式需要手动修改构造器的指向,不然输出的实例对象和构造函数的原型对象中没有构造器
    constructor: Person,// 手动在原型对象中添加构造函数属性
    sayHi: function () { // 需要进行共享的数据
        console.log("您好");
    }
};
  1. 原型对象中的方法是可以相互调用的
  2. 实例对象调用的属性和方法,先在实例对象中查找是否有这些属性和方法,找到了则直接使用,找不到就到实例对象的__ proto__指向的原型对象prototype中找,找到了就使用,找不到就报错 —— 原型链
  3. 我们可以为系统的内置对象的原型对象中添加方法,也就是我们可以修改系统的源码
  4. 把局部变量变为全局变量 —— 把局部变量给window作为window的一个属性即可
原型链
什么是原型链?

指的是一种关系,是实例对象和原型对象之间的关系,这种关系是通过实例对象的下划线原型(__ proto__)联系的

  • 构造函数中的this就是实例对象,原型对象方法中的this也是实例对象
  • 实例对象的原型__ proto__指向的是其所在构造函数的原型prototype,构造函数的原型对象(prototype)的指向改变,那么实例对象的原型指向也会改变
  • 原型的指向可以改变,即原型链是可以改变的
  • 实例对象中有__ proto__原型,构造函数中有prototype原型,prototype是对象,所以,prototype对象中也有下划线原型,实例对象的下划线原型指向的是其所在的构造函数的原型对象,那么prototype对象的下划线原型对象指向的也是某一个构造函数中的原型对象 —— 只要是对象就有下划线原型,只要是下划线原型那么它指向的一定是某一个构造函数的原型对象,原型链的终端是Object的原型对象,Object的原型对象的下划线原型是null
  • 如果原型对象指向改变了,欲添加原型方法,应该先改变指向再给原型对象添加方法
实例对象和原型对象属性重名问题

实例对象访问某个属性,会先在实例对象中找是否存在这个属性,找不到就到其原型对象中找,最终找不到就是undefined(不会报错,因为JS是一门动态类型的语言,只要点了对象就有了这个属性,又由于属性没有赋值所以就是undefined)—— 层层查找

一个很神奇的原型链

实例对象中的下划线原型一定指向的是某个构造函数的原型对象

  • divObj.__ proto__ —— HTMLDivElement.prototype
  • HTMLDivElement.prototype中的__ proto__ —— HTMLElement.prototype
  • HTMLElement.prototype中的__ proto__ —— Element.prototype
  • Element.prototype中的__ proto__ —— Node.prototype
  • Node.prototype中的__ proto__ —— EventTarget.prototype
  • EventTarget.prototype中的__ proto__ —— Object.prototype
  • Object中没有下划线原型对象,即Object.prototype中的__ proto__ —— null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript中,每个对象都有一个隐藏的 `__proto__` 属性,它指向该对象的原型原型是一个普通的对象,它包含了共享属性和方法。当我们访问一个对象的属性或方法时,JavaScript引擎会首先在该对象本身查找,如果找不到,则会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的顶端(Object.prototype)。这个原型链的过程就是通过 `__proto__` 属性来实现的。 例如,当我们创建一个实例对象 `teacher` 时,如果 `teacher` 对象本身没有 `teach()` 方法,JavaScript引擎会通过对象的 `__proto__` 属性查找到 `Teacher.prototype` 的显式原型上,如果 `Teacher.prototype` 仍然没有该方法,它会继续沿着 `Teacher.prototype.__proto__` 找到 `Person.prototype`,直到找到 `teach()` 方法并执行。这样就形成了一个原型链。 同时,可以注意到 `Object.prototype.__proto__` 的值为 `null`,即 `Object.prototype` 没有原型。所以在原型链中,当找到顶层原型还没有属性时,就会返回 `undefined`。 需要注意的是, `__proto__` 是一个非标准的属性,实际开发中不应该直接使用它。它只是内部指向原型对象 `prototype` 的一个指示器,我们应该使用 `Object.getPrototypeOf()` 或 `Object.setPrototypeOf()` 来访问和设置对象的原型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [JS原型原型链](https://blog.csdn.net/elevenhope/article/details/122882582)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [JavaScript原型链(重要)](https://blog.csdn.net/liyuchenii/article/details/125957625)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值