首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我们可以先修复构造函数属性,然后重置原型?

在JavaScript中,对象的构造函数属性和原型是两个不同的概念。

构造函数属性是指对象的一个特殊属性,它指向创建该对象的构造函数。通过构造函数创建的对象会自动拥有该属性,并且可以通过该属性访问到构造函数本身。

原型是JavaScript中实现继承的一种机制。每个对象都有一个原型,它定义了对象的共享属性和方法。当我们访问一个对象的属性或方法时,如果对象本身没有该属性或方法,JavaScript会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的顶端。

为什么我们可以先修复构造函数属性,然后重置原型呢?

修复构造函数属性的目的是确保对象的构造函数属性指向正确的构造函数。有时候,在对象被创建后,我们可能会修改对象的原型,或者将对象赋值给其他对象,这可能会导致对象的构造函数属性指向错误的构造函数。通过先修复构造函数属性,我们可以确保对象的构造函数属性始终指向正确的构造函数。

重置原型的目的是确保对象的原型链是正确的。当我们修改一个对象的原型时,原型链可能会被打破,导致对象无法正确继承原型链上的属性和方法。通过重置原型,我们可以修复原型链,确保对象能够正确继承原型链上的属性和方法。

总结起来,先修复构造函数属性,然后重置原型的目的是确保对象的构造函数属性和原型链是正确的,以保证对象能够正确继承属性和方法。

腾讯云相关产品和产品介绍链接地址:

  • 云服务器(ECS):提供安全、高性能、可扩展的云服务器实例,满足各种计算需求。详情请参考:https://cloud.tencent.com/product/cvm
  • 云数据库 MySQL 版(CDB):提供稳定可靠的云数据库服务,支持高可用、备份恢复、性能优化等功能。详情请参考:https://cloud.tencent.com/product/cdb
  • 人工智能平台(AI Lab):提供丰富的人工智能开发工具和服务,包括图像识别、语音识别、自然语言处理等。详情请参考:https://cloud.tencent.com/product/ailab
  • 物联网套件(IoT Hub):提供全面的物联网解决方案,包括设备接入、数据管理、消息通信等功能。详情请参考:https://cloud.tencent.com/product/iothub
  • 云存储(COS):提供安全可靠的云存储服务,支持海量数据存储、多媒体处理、数据备份等。详情请参考:https://cloud.tencent.com/product/cos
  • 区块链服务(BCS):提供一站式区块链解决方案,包括区块链网络搭建、智能合约开发、数据上链等功能。详情请参考:https://cloud.tencent.com/product/bcs
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

JavaScript难点:原型原型链、继承、new、prototype和constructor

实例对象的原型属性可以用 __proto__ 访问到,推荐用 Object.getPrototypeOf() 去获取。...原型链 任何一个实例,通过原型链,都能找到它上面的原型,该原型对象中的方法和属性可以被所有的原型实例共享,原型对象中依然有它自身的原型,当我们访问一个实例属性或方法时,如果自身没有,就会一级一级地去原型对象上找...当我们 new 的时候实际会调用内部的 constructor 构造函数,会做以下4步: 新建一个对象 将对象的原型指向构造函数的 prototype 绑定 this,执行构造函数中的代码 返回对象...为什么通过 prototype 修改原型实现继承后要重置 custructor?...我们可以通过将一个构造函数的 prototype 指向另一个构造函数来实现继承父类的属性和方法,但是往往还会额外加一个 Child.prototype.constructor = Child,这是因为直接通过

10310

JavaScript 中的六种继承方式

特点: 实例可继承的属性有:实例的构造函数属性,父类构造函数属性,父类原型上的属性。...特点: 只继承了父类构造函数属性,没有继承父类原型属性 解决了原型链继承的注意事项(缺点)1,2,3 可以继承多个构造函数属性(call可以多个) 在子实例中可以向父实例传参 注意事项: 只能继承父类构造函数属性...,可以传参,可复用 每个新实例引入的构造函数属性是私有的 注意事项: 调用了两次父类的构造函数(耗内存) 子类的构造函数会代替原型上的那个父类构造函数(call相当于拿到了父类构造函数的副本) 原型式继承...,然后返回这个函数的调用,这个函数就变成了可以随意增添属性的实例或对象。...为什么要修正子类的构造函数的指向呢? 因为在不修正这个指向的时候,在获取构造函数返回的时候,在调用同名属性或方法取值上可能造成混乱。

47620

我来重新学习 javascript 的面向对象(part 3)

和 动态原型模式 一、组合使用构造函数模式和原型模式 组合使用构造函数模式和原型模式的特点主要体现在: 构造函数模式用于定义实例属性 原型模式用于定义方法和共享属性 效果就是,每个实例对象都会有自己的一份实例属性...,这样就不怕之前出现的 new 实例化对象,然后再添加原型对象的属性的问题了(回想一下原型对象被重写之后,原型对象丢失,实例无法使用原来的原型对象的数据的问题)。...更符合 OOP 开发习惯,不需要将构造函数原型对象分开单独处理,可以写在一起。...(因为他每次都会new Object(),重置原型对象的信息) 四、稳妥构造函数模式 这个只是了解一下即可,因为实际中我还没用过,但是需要扩大知识面,无论从装逼还是装逼都还是需要的。...(因为他每次都会new Object(),重置原型对象的信息) 五、文末我们又遇到新问题了 公司业务越来越大了,公司的产品需要做一些分类,例如动物要分肉食动物,菜食动物,食物要分水果和蔬菜和肉类等,水果下面还要分苹果

35510

知其然,知其所以然,JS 对象创建与继承

,需要多处进行增删改; 工厂函数 肯定是要封装啦,第一个反应,可以 借助函数 来帮助我们批量创建对象~ 于是乎: function makeCar(price,color,performance){...构造+原型 新的问题在于,我们不能通过查找原型链从 MakeCarChild 找到 MakeCar car4....为什么“子类要继承父类原型上的属性”?就靠 this 绑定来找不行吗?...万物由上帝创造(对象由函数构造而来),上帝本身也属于一种物质(函数本身却也是对象); 对于本篇来说,继承,其实都是父子构造函数在继承,然后再由构造函数实例化对象,以此来实现对象的继承。...都是吧~~ ---- 小结 本篇由创建对象说起,讲了工厂函数,它可以做一层最基本的封装; 再到,对工厂的拓展,演进为构造函数; 再基于原型特点,构造+原型,得出组合继承; 再追求极致,讲到寄生组合; 再讲到简化书写的

49040

JavaScript 进阶教程(1)--面向对象编程

(这种方式不严谨,推荐使用 instanceof 操作符,后面学原型会解释为什么) 3.6 构造函数的问题 使用构造函数带来的最大的好处就是创建对象更方便了,但是其本身也存在一个浪费内存的问题: function...这个对象的所有属性和方法,都会被构造函数的实例继承。 这也就意味着,我们可以把所有对象实例需要共享的属性和方法直接定义在 prototype 对象上。...4.2 属性成员的搜索原则:原型链 了解了 构造函数-实例-原型对象 三者之间的关系后,接下来我们来解释一下为什么实例对象可以访问原型对象中的成员。...然后,它继续搜索,再问:“ person1 的原型有 sayName 属性吗?”答:“有。 于是,它就读取那个保存在原型对象中的函数。...原型对象使用建议: 私有成员(一般就是非函数成员)放到构造函数中。 共享成员(一般就是函数)放到原型对象中。 如果重置了 prototype 记得修正 constructor 的指向。

49443

JavaScript深入浅出补充——(二)语句和严格模式,对象

抛出异常,然后catch处理,finally,然后因为catch又抛出了这个异常,所以外面在处理,也就是如果里面的异常没有处理抛出了,它会在外面处理,但是要执行里面的finally  function...语句 function语句用来定义函数对象,用function定义的函数我们叫做函数声明,与之对应的另一种我们叫做函数表达式,如下 他们的最主要的区别就是函数声明会被预先处理,或者叫函数前置 还可以通过...new function 构造器的方式来创建函数对象 for …in语句 这里我们可以用for  in去遍历obj中的属性  switch语句 如下三种方法 循环语句 with语句 可以修改当前的作用域...对象的字符串key 对象的构造 每个对象除了标签和方法之外还有原型 比如我们创建一个函数 foo  每一个函数都会有一个prototype这样一个对象属性 如果我们吧foo.prototype.z 设置为...定义的变量或者局部变量仍然不可以被删除 函数声明也是同理,或者函数内部的局部作用域的函数,都不可以被删除 如果饮食的创建全局变量,没有定义ohNo,我们可以用window.

80140

秒懂JS对象、构造函数原型对象之间的关系

一、基本概念   1、对象:属性和方法的集合,即变量和函数的封装。每个对象都有一个__proto__属性,指向这个对象的构造函数原型对象。   ...3、原型对象:每个函数都有一个prototype属性,它是一个指向原型对象的指针(原型对象在定义函数时同时被创建) 二、创建对象的方法   1、使用构造函数原型对象共同创建 ?...如上图,构造函数Person(),通过new关键字创建了两个实例化对象p1、p2,这两个新对象都继承了,构造器Person()函数prototype属性所指向的原型对象。...} Person.prototype = {//设置构造函数prototype指定的对象,即重置原型对象 constructor : Person, sayName : function...妈让每个孩子拥有私有能力,爸让它们拥有共有能力(这个共有能力其实都是爸代劳的/(ㄒoㄒ)/~~);没有构造函数的情况下,可以直接理解为克隆哦~怎么样,这样应该能理解三者之间的关系了吧。

1.7K70

JS完美收官之——继承发展史

原型上的隐式属性__proto__可以访问到图(1)中的lastName属性,这个__proto__就是原型链,这个属性只能系统内部去使用,开发者是用不了的。...Student的构造函数,但是Person已经实现了我们部分功能,所以在Student中我们可以用Person中的方法就可以了。...借用构造函数弊端: 1.只能继承在构造函数中的方法,却不能继承那些添加到原型中的方法。 2. 这种继承每次要多调用一个函数,只是在视觉上省代码,实际运行上还浪费效率了。...,同时还可以继续共享原型上的属性,但改变子对象上原型属性时,祖对象原型不受影响。...好使没问题,我们的目的达到了,几乎完美了,但是还差点,我们还需要重置构造函数指针,,如果不重置,那么所有子对象都会显示Father()是它们的构造函数,造成指向紊乱了,所以我们可以归下位: Father.prototype.name

37620

前端入门13-JavaScript进阶之原型声明正文-原型

所以,可以通俗的理解,构造函数只是作为第三方类似于工具的角色,用来创建一个新对象,然后让这个新对象继承自 prototype 属性指向的对象。...所以,所有从这个构造函数创建的新对象,都继承了原型属性,那么这些新对象也就可以通过继承而来的 constructor 的属性访问构造函数。...还有一种,定义一个新的原型对象,然后重新赋值构造函数的 prototype 属性值,将它指向新的原型对象。但这种方式会破坏默认的原型链,同时也会破坏构造函数原型、实例化对象三者间的默认关联关系。...对于对象 a,我们创建它的方式并没有手动去修改它的原型链,所以按默认的三者间的关系,Array.prototype 的 constructor 属性指向构造函数 Array(),这就是为什么 b....通常是不建议通过这种方式来实现继承,因为这样会破坏默认的三者间的联系,除非手动修复,手动对 a 的 constructor 属性赋值为 A,这样可以手动修复三者间默认的关联。

62030

《JavaScript 模式》读书笔记(6)— 代码复用模式2

原型链   当使用本模式以及熟悉的Parent()和Child()构造函数时,让我们来看原型链(prototype chain)的工作流程。...下面这个模式将解决这个问题 五、类式继承模式#3——借用和设置原型 类式继承模式#3主要思想是结合前两种模式,即先借用构造函数然后还设置子构造函数原型使其指向一个构造函数创建的新实例。...还可以注意到name属性却被继承了两次,在我们删除了kid本身的name属性的副本后,随后看到的输出是原型链表现出来所引出的name属性。   下图显示了对象之间的链接关系。...如果不重置构造函数的指针,那么所有子对象将会报告Parent()是它们的构造函数,这是没有任何用处的。...可以重置constructor属性使其指向期望的构造函数且不会影响其功能,这是由于该属性主要是用于提供对象的信息。

34110

JavaScript实现继承的六种方式

,不能在构造函数中 无法实现多继承 创建子类实例时,不能向父类构造函数传参数 所有新实例都会共享父类实例的属性。...存在的问题: prototype里有个属性constructor指向构造函数本身,但是, Student的原型已经被父类的实例取代了,所以指向也不正确,所以需要修复构造函数指向(这里网上的教程只是对组合继承...借用构造函数继承 在一个类中执行另一个类的构造函数,通过 call函数设置 this的指向,这样就可以得到另一个类的所有属性 function WebsiteMaster(site) { this.site...可以实现多继承(call 多个对象) 不需要修复构造函数指向 缺点: 方法在构造函数中定义,无法复用 只能继承父类的实例属性,不能继承原型属性、方法 实例并不是父类的实例,而只是子类的实例 stu instanceof...、方法,也可以继承原型属性、方法 可传参、可复用 实例既是子类的实例,也是父类的实例 缺点: 调用了两次父类构造函数,耗内存 需要修复构造函数指向 6.

51740

JavaScript继承的实现方式:原型语言对象继承对象原理剖析

初始化内部属性 :这一步骤不是必要的。通俗点说,就是,对”复制品”不满意,我们可以”再加工”,使之获得不同于”模板”的”个性”。  所以在JavaScript的世界里,万物皆对象这个概念从一而终。...: 可以在子类中增加实例属性,如果要新增加原型属性和方法需要在new 父类构造函数的后面 无法实现多继承 来自原型对象的所有属性被所有实例共享,子类可以重写父类原型上的方法 创建子类实例时,不能向父类构造函数中传参数...解决了子类实例共享父类引用属性的问题 可以实现多继承(call或者apply多个父类) 借用构造函数继承缺点: 方法都在构造函数中定义,无法复用 不能继承原型属性/方法,只能继承父类的实例属性和方法...不存在引用属性问题 可以继承属性和方法,并且可以继承原型属性和方法 寄生组合继承 通过寄生的方式来修复组合式继承的不足,完美的实现继承 function Woman(name,age){   //继承父类属性...ES6 的继承机制完全不同,实质是创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。

75420

轻松理解JS中的面向对象,顺便搞懂prototype和__proto__

puppyAge,也就是小狗的年龄,然后有一个构造函数Puppy(),这个构造函数接收一个参数,可以设置小狗的年龄,另外还有一个说话的函数say。...这么设计的目的就是让使用者可以通过构造函数给实例对象设置属性,这时候console出来看myPuppy.puppyAge就是2。...prototype.constructor是prototype上的一个保留属性,这个属性就指向类函数本身,用于指示当前类的构造函数。 ? ?...既然prototype.constructor是指向构造函数的一个指针,那我们是不是可以通过它来修改构造函数呢?我们来试试就知道了。...我们修改下这个函数然后新建一个实例看看效果: function Puppy(age) { this.puppyAge = age; } Puppy.prototype.constructor

2.4K62

JavaScript 进阶教程(3)---让你彻底搞懂原型链和继承

上图中红线链接部分即Person实例对象和Person原型对象之间的关系,可以看成一个原型链(不完整,目前可以这样理解)。...注意:简单的原型写法,会将 Person.prototype 重置到了一个新的对象,即改变原型的指向。我们也应该在原型改变指向之后添加原型方法。...要想实现这个需求,就要创建对象,要想创建对象,就应该有构造函数然后通过构造函数来创建对象,通过对象调用属性和方法来实现相应的功能及需求。...2.1 什么是继承 继承是一种类(class)与类之间的关系,JS中没有类,但是可以通过构造函数模拟类,然后通过原型来实现继承,继承是为了实现数据共享,js中的继承当然也是为了实现数据共享。...2.5 组合继承 原型继承和借用构造函数继承都存在各自的缺点,我们可以将这二者结合到一起,从而发挥二者之长。即在继承过程中,既可以保证每个实例都有它自己的属性,又能做到对一些属性和方法的复用。

47142

【JS原理】代码版认干爹 - 继承

Person,很明显,你已经认错妈了,这分明不符合伦理啊,认了干爹,不能忘了妈啊 幸好,我们有办法修复你的忘恩负义 Student.prototype.constructor = Student 无法向父类传递参数...属性污染 这里说的是 父类的构造函数会有一个 对象属性然后大家都可以操作他,导致 共享污染 但是我想想,这是 原型链继承的问题吗???这是原型都会存在的问题!!...= new Student() 缺点 无法继承父类属性方法 可以传递参数给父类构造函数,自定义属性 3组合继承 function Person(){} function Student(){ Person.call...Object.create 传入 一个对象 a,会返回一个对象 b 你可以看到 对象a 成了 对象 b 的原型 所以 Object.create 可以说成是 为 新对象指向原型的一个方法 那我们现在...__proto__ 而后我有个想法,为什么要增加访问深度,这样不是会更慢吗?我可不可以这样 Student.prototype=Person.prototype 哎呀,我去,可以呀,这样不是完美了??

66840

《JavaScript 模式》读书笔记(6)— 代码复用模式2「建议收藏」

下面这个模式将解决这个问题 五、类式继承模式#3——借用和设置原型 类式继承模式#3主要思想是结合前两种模式,即先借用构造函数然后还设置子构造函数原型使其指向一个构造函数创建的新实例。...还可以注意到name属性却被继承了两次,在我们删除了kid本身的name属性的副本后,随后看到的输出是原型链表现出来所引出的name属性。   下图显示了对象之间的链接关系。...最后,针对这个几乎完美的类式继承函数,还需要做的一件事情就是重置构造函数的指针,以免在将来的某个时候还需要该构造函数。   ...如果不重置构造函数的指针,那么所有子对象将会报告Parent()是它们的构造函数,这是没有任何用处的。...可以重置constructor属性使其指向期望的构造函数且不会影响其功能,这是由于该属性主要是用于提供对象的信息。

19920

前端面试(2)javascript

在 js 中我们使用构造函数来创建一个新的对象,每个构造函数内部都有一个 prototype 属性值,这个属性值是一个对象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。...3、组合继承(原型链继承和构造函数继承) 核心:用原型链实现对原型属性和方法的继承,用借用构造函数技术来实现实例属性的继承。...(原型链继承和构造函数继承的组合,兼具了二者的优点) 优点: 父类的方法可以被复用 父类的引用属性不会被共享 子类构建实例时可以向父类传递参数 缺点: 调用了两次父类的构造函数,第一次给子类的原型添加了父类的...而实际上,我们希望子类实例的构造函数是Child,所以要记得修复构造函数指向。...但是, 寄生组合继承是创建子类实例 this 对象,然后再对其增强; 而 ES6 先将父类实例对象的属性和方法,加到 this 上面(所以必须先调用 super 方法),然后再用子类的构造函数修改 this

1.2K20

【THE LAST TIME】一文吃透所有JS原型相关知识点

暂且我们不管上面的代码有什么意义。至少,我们能看出,都是对象,却存在着差异性 其实在 JavaScript 中,我们将对象分为函数对象和普通对象。...此外因为 shift 会修改原数组,所以 arguments 会被去除第一个参数 将 obj 的原型指向构造函数,这样 obj 就可以访问到构造函数原型中的属性 使用 apply,改变构造函数 this...我们需要继承的仅仅是父类的原型,不用去调用父类的构造函数。换句话说,在构造函数继承中,我们已经调用了父类的构造函数。...子类对象,因此在寄生式继承中要对复制对象p做一次增强,修复起constructor属性指向性不正确的问题,最后将得到的复制对象p赋值给子类原型,这样子类的原型就继承了父类的原型并且没有执行父类的构造函数...其中super 关键字表示父类的构造函数,相当于 ES5 的 Parent.call(this),然后再根据我们上文说到的继承方式,有没有感觉该集成的实现跟我们说的寄生组合式继承非常的相似呢?

1K10

JS原生方法原理探究(六)从 Babel 转译过程浅谈 ES6 实现继承的原理

,有的函数不是我们讨论的重点,而且也完全可以单独拎出来分析,所以这里简单把它们的作用介绍了,之后如果忘记了函数的作用,翻到这里来看即可。...这里我们会看到还传入了第二个参数,这个参数是子类原型属性的特性描述对象(descriptor),我们对 constructor 属性进行了设置,将它设置为可写、可配置,同时利用 value 修复了因重写子类原型而丢失的...可以看到,通过调用 _inherit 函数我们已经成功让子类继承了父类的原型方法和静态方法。不过,实例上的属性怎么继承呢?...现在,让我们再回到 Son 构造函数可以看到,调用它之后返回的正是 _super.call(this),也就是返回 result 或者经过增强的this。...这里的 result 我们知道也有两种取值,如果是一个继承了父类实例所有属性的子类实例,那么实际上等价于经过增强的 this;如果是父类构造函数中自定义返回的一个非空对象,则意味着调用 Son构造函数之后返回的对象实际上并没有继承父类中声明的实例属性

1.1K10

JS原生方法原理探究(六)从 Babel 转译过程浅谈 ES6 实现继承的原理

,有的函数不是我们讨论的重点,而且也完全可以单独拎出来分析,所以这里简单把它们的作用介绍了,之后如果忘记了函数的作用,翻到这里来看即可。...这里我们会看到还传入了第二个参数,这个参数是子类原型属性的特性描述对象(descriptor),我们对 constructor 属性进行了设置,将它设置为可写、可配置,同时利用 value 修复了因重写子类原型而丢失的...可以看到,通过调用 _inherit 函数我们已经成功让子类继承了父类的原型方法和静态方法。不过,实例上的属性怎么继承呢?...现在,让我们再回到 Son 构造函数可以看到,调用它之后返回的正是 _super.call(this),也就是返回 result 或者经过增强的this。...这里的 result 我们知道也有两种取值,如果是一个继承了父类实例所有属性的子类实例,那么实际上等价于经过增强的 this;如果是父类构造函数中自定义返回的一个非空对象,则意味着调用 Son构造函数之后返回的对象实际上并没有继承父类中声明的实例属性

1.1K20
领券