推广

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

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

原型对象有一个自有属性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://www.0291.com.cn/post/56690.html

相关文章

如何在知乎上打广告?

如何在知乎上打广告?

一、什么是知乎信息流广告? 位于动态、或者资讯内容中的的广告,广告的形式有图片、图文、视频等,特点是算法推荐、原生体验,可以通过标签进行定向投放,根据自己的需求进行选择。 二、知乎广告–知+是什么? 「知+ 」知乎官方为个人和为企业的商 业增长提供了整体的内容解...

我来教你低质量导入链接,会提高你的网站推广排名吗。

我来教你低质量导入链接,会提高你的网站推广排名吗。

在SEO排名工作中,外部链接的构建是我们每天讨论的话题。众所周知,在不断更新百度算法之后,高和相关的外部链接是我们的首选操作方法,但是仍然有许多SEO新手不遗余力地发送大量低质量的外部链接。他们真的对您的排名有意义吗?那么,什么是低质量的传入链接(垃圾邮件链接)? 一般来自于非相关的...

新站期攻坚良法之-----内容篇。

新站期攻坚良法之-----内容篇。

每一个新的网站上线,搜索引擎都会对其进行考察,这是不可避免的,相信每位站长都对新站期比较无奈:排名不稳定,收录不快,快照进展不顺等等问题,如何去攻坚新站期让新站期尽可能的缩短? 是否一上来就发布大量外链? 答案肯定是不行的,这样相反会增加搜索引擎对网站的审核时间,基于现在的绿萝算法...

深层次解答网站seo优化过程中出现的客户疑虑。

深层次解答网站seo优化过程中出现的客户疑虑。

一、是一项长期的工作 在SEM中,SEO技术与竞价排名之间存在一定的差异。一般来说,只要关键词竞价提高,排名就能马上提升,但SEO工作就不能这么立竿见影。SEO是一项长期的工作,有效周期长,需要时间的积累才能有收获。因此,从事SEO行业,我们不能急于求成,也不能半途而废,树立正确的S...

产品思维,到底是个什么玩意儿(一)

产品思维,到底是个什么玩意儿(一)

一款产品,首先要服务于用户,让用户满意并了解它的价值。想要做好一款产品,对于产品经理而言就需要具备一定的产品,那么什么是产品思维呢?作者将分享他对产品思维的思考,希望能对你有所帮助。 作为产品的你,一定对“产品思维”这个词非常...

只做网站优化排名,不考虑关键词和内容的转化是没有意义的。

只做网站优化排名,不考虑关键词和内容的转化是没有意义的。

对于很多企业网站来说,很多网站在做时只看自己关键词的排名,而没有做好关键词和内容的转化。甚至很多企业网站都找一些专业的网站建设和优化排名公司,但他们只看重排名指标,但有了排名,收入如何? 在日常工作中,我们不能忘记网站建设和优化的目的,即盈利。一方面,我们网站优化的目的是为了获得一个...

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

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