推广

JavaScript面试考点之原型及原型链

iseeyu2年前 (2024-02-21)推广145

原型对象有一个自有属性constructor,这个属性指向该函数。关系图如下:

2)原型链

当访一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

构造函数Person存在原型对象是Person.prototype;

构造函数生成实例对象person,person的__proto__指向构造函数Person原型对象;

Person.prototype.__proto__ 指向内置对象,因为 Person.prototype 是个对象,默认是由 Object函数作为类创建的,而 Object.prototype 为内置对象;

Person.__proto__指向内置匿名函数anonymous,因为 Person 是个函数对象,默认由 Function 作为类创建。

Function.prototype和Function.__proto__同时指向内置匿名函数anonymous,这样原型链的终点就是null。

总结:

__proto__和prototype关系:__proto__和constructor是对象独有的。prototype属性是函数独有的

__proto__作为不同对象之间的桥梁,用来指向创建它的构造函数的原型对象的。

每个对象的__proto__都是指向它的构造函数的原型对象prototype的;

构造函数是一个函数对象,是通过 Function构造器产生的;

原型对象本身是一个普通对象,而普通对象的构造函数都是Object;

所有的构造器都是函数对象,函数对象都是 Function构造产生的;

Object的原型对象也有__proto__属性指向null,null是原型链的顶端。

a、一切对象都是继承自Object对象,Object 对象直接继承根源对象null

b、一切的函数对象(包括 Object 对象),都是继承自 Function 对象

c、Object 对象直接继承自 Function 对象

d、Function对象的__proto__会指向自己的原型对象,最终还是继承自Object对象

实例.__proto__ === 原型

原型.constructor === 构造函数

构造函数.prototype === 原型

js 获取原型的方法:

p.proto

p.constructor.prototype

Object.getPrototypeOf(p)

思考:Number.prototype.constructor === Number.constructor 结果相等吗?

答案是不相等。因为Number.prototype.constructor 查找的是自己 Number 原型上的构造函数。Number是没有有 constructor 属性,就会原型链的 __proto__ 向上查找上一级类(这里是函数)的原型,函数的 constructor 指向 Function。所以不同。

2、判断属性是否继承自原型链

JavaScript中Object对象原型上的hasOwnProperty()用来判断一个属性是定义在对象本身而不是继承自原型链。

因为JavaScript没有将hasOwnProperty作为一个敏感词,所以我们很有可能将对象的一个属性命名为hasOwnProperty,这样一来就无法再使用对象原型的 hasOwnProperty 方法来判断属性是否是来自原型链。

则我们需要使用原型链上真正的 hasOwnProperty 方法

3、属性遍历方法

Object.keys() 方法会返回一个由给定对象的所有可枚举自身属性的属性名组成的数组,不包括继承自原型的属性和不可枚举的属性。

Reflect.ownKeys()返回所有自有属性key,不管是否可枚举,但不包括继承自原型的属性。

for in主要用于遍历对象的可枚举属性,包括自有属性、继承自原型的属性。

Object.assign()          //会忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。

使用Object.defineProperty()方法设置enumerable,Object.defineProperty(obj, prop, descriptor)方法有三个参数

obj:目标对象

prop:目标属性,字符串

descriptor:对目标属性的行为,放在对象里

enumerable为true时表示可枚举,enumerable为false表示不可枚举;

每个对象都有propertyIsEnumerable()方法,这个方法可以判断出指定的属性是否可枚举。propertyIsEnumerable方法只对对象自身的属性(对象自身添加的、构造函数实例化的)有效,对原型上的、继承来的属性都无效。

obj.propertyIsEnumerable(“属性名”);

1)这个属性必须属于实例的,并且不属于原型。

2)这个属性必须是可枚举的。

3)如果对象没有指定的属性,该方法返回false

4、对new的理解

new操作符用于创建一个给定构造函数的实例对象。

new的流程:

a、创建一个新的对象obj;

b、将对象与构建函数通过原型链连接起来;

c、将构建函数中的this绑定到新建的对象obj上;

d、根据构建函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理。(new 关键词执行之后总是会返回一个对象,要么是实例对象,要么是 return 语句指定的对象)

当构造函数最后return出来的是一个和this无关的对象时,new 命令会直接返回这个新对象,而不是通过 new 执行步骤生成的 this 对象。

但是这里要求构造函数必须是返回一个对象,如果返回的不是对象,那么还是会按照 new 的实现步骤,返回新生成的对象。

手写new

a、使用Object.create将obj 的proto指向为构造函数的原型;

b、使用apply方法,将构造函数内的this指向为obj;

c、在create返回时,使用三目运算符决定返回结果。

构造函数如果有显式返回值,且返回值为对象类型,那么构造函数返回结果不再是目标实例

5、继承

1)原型继承

直接让子类的原型对象指向父类实例,当子类实例找不到对应的属性和方法时,就会往它的原型对象,也就是父类实例上找,从而实现对父类的属性和方法的继承。

缺点:它是通过链式继承的,属于引用类型传值,不是复制一份,引用副本实例属性的修改必然会引起其他副本实例属性的修改。

2)call继承(构造函数继承)

构造函数继承,即在子类的构造函数中执行父类的构造函数,并为其绑定子类的this,让父类的构造函数把成员属性和方法都挂到子类的this上去,这样既能避免实例之间共享一个原型实例,又能向父类构造方法传参。

复制一份,子类的实例各自得到一份构造函数的副本,属于值传递,所以子类之间的属性修改是互不相关的,跟父类就没有关系了。

缺点:继承不到父类原型上的属性和方法。

3)组合式继承

原型继承+call继承。在子类的构造函数中通过Parent.call(this)继承父类的属性,然后改变子类的原型为new Parent()来继承父类的函数。

缺点:每次创建子类实例都执行了两次构造函数(Parent.call()和new Parent()),虽然这并不影响对父类的继承,但子类创建实例时,原型中会存在两份相同的属性和方法

4)寄生组合式继承

为了解决每次创建子类实例都执行了两次构造函数的问题,私有的只拿私有的,用call来做。共有只拿共有的,用Object.create()来做。

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://0291.com.cn/post/56690.html

相关文章

品牌营销策略分析类毕业论文文献包含哪些?

品牌营销策略分析类毕业论文文献包含哪些?

本文是为大家整理的策略分析主题相关的10篇毕业论文文献,包括5篇期刊论文和5篇学位论文,为品牌营销策略分析选题相关人员撰写毕业论文提供参考。1.【期刊论文】5G时代背景下华为手机品牌营销策略分析期刊:《中小企业管理与科技》 | 2021 年第 002 期摘要:随着5G的迅...

为什么 2023 联想拯救者发布之后,大家都说今年 ROG 变成 ...

为什么 2023 联想拯救者发布之后,大家都说今年 ROG 变成 ...

为什么 2023 联想拯救者发布之后,大家都说今年 ROG 变成 ......

购物娱乐:亚太地区的万亿美元机遇报告。

购物娱乐:亚太地区的万亿美元机遇报告。

波士顿咨询发布了新报告"购物娱乐——亚太地区的万亿美元机遇"。报告预计到2025年娱乐化消费市值将达到1万亿美元。目前的市场价值为5000亿美元。高增长市场预计将享受63%的复合年增长率。 购物娱乐的定义 购物娱乐被定义为内容驱动的商业,它首先寻求娱乐和教育,同时整合内容和社区以创造高度身临其境...

可能是最佳动效方案!腾讯免费动效设计神器 PAG。

可能是最佳动效方案!腾讯免费动效设计神器 PAG。

今天给大家推荐一款未来很有可能会成为主流的动画解决方案 —— PAG。 一、常见动效落地方案 1. Lottie 它算是市面上比较普遍的一种动效落地方式,它可以制作很多种类的矢量动画以及图片动画,它的缓动曲线会占用很多内存,在各平台效果支持上也不是特别的稳定,而且 Lottie 所支...

seo优化外包公司应该保持四种心态服务好seo客户。

seo优化外包公司应该保持四种心态服务好seo客户。

首先,心平气和 冷静下来,你可以说SEO需要一种心态。搜索引擎是我们做不到的,即使我们可以去学习和掌握搜索引擎的细节,但它是一个不断变化的,算法是不断变化的,因此,由于每一个搜索引擎的变化,我们应该保持心态,冷静状态,收集,外链,排名,其实,看看一些流量小,我们只需要记住一个一句话,...

建立提升产品转化率的系统化思维

建立提升产品转化率的系统化思维

编辑导语:如何有效地提升产品整体转化率?在产品设计层上,你可能需要了解产品的面向用户、以及可能影响用户消费决策的关键点,最后建立有关产品转化提升的整体。本篇文章里,作者就以互联网产品为例,对如何提升产品转化率一事进行了拆解,一起来看。...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片