资讯专栏INFORMATION COLUMN

揭开JS中constructor的秘密

MorePainMoreGain / 1429人阅读

摘要:学习原型与继承的时候,经常会碰到,现在来揭开神秘面纱描述所有对象都会从它的原型上继承一个属性继承中的用于设置原型重新分配原始构造函数现在不手动重置构造函数用于设置原型重新分配原始构造函数可以看到除了的不同,重置不重置原始构造函数对我们的继承

学习js原型与继承的时候,经常会碰到constructor,现在来揭开神秘面纱
描述:所有对象都会从它的原型上继承一个 constructor 属性
var o = new Object;
o.constructor === Object; // true

var a = [];
a.constructor === Array; // true

var a = new Array;
a.constructor === Array // true

var n = new Number(3);
n.constructor === Number; // true
继承中的constructor
function Person (name, age) {
  this.name = name,
  this.age = age
}
Person.prototype.setAge = function () {
  console.log("111")
}
function Student (name, age, price) {
  Person.call(this, name, age)
  this.price = price
  this.setScore = function () { }
}
Student.prototype = Object.create(Person.prototype)//用于设置原型
Student.prototype.constructor = Student//重新分配原始构造函数
var s1 = new Student("Tom", 20, 15000)
console.log(s1 instanceof Student, s1 instanceof Person) // true true
s1.setAge() // 111
console.log(s1)  
console.log(s1.constructor) //Student

现在不手动重置构造函数

function Person (name, age) {
  this.name = name,
  this.age = age
}
Person.prototype.setAge = function () {
  console.log("111")
}
function Student (name, age, price) {
  Person.call(this, name, age)
  this.price = price
  this.setScore = function () { }
}
Student.prototype = Object.create(Person.prototype)//用于设置原型
// Student.prototype.constructor = Student//重新分配原始构造函数
var s1 = new Student("Tom", 20, 15000)
console.log(s1 instanceof Student, s1 instanceof Person) // true true
s1.setAge() // 111
console.log(s1)  
console.log(s1.constructor) // Person


可以看到除了s1的constructor不同,重置不重置原始构造函数对我们的继承没有影响。

结论就是:constructor是用于识别对象是由哪个构造函数初始化的,对继承没影响
可以看这篇文章:JS constructor探讨(一):为什么要设置prototype.constructor?

But!! 什么情况下要手动重置构造函数??? 那就是你要调用constructor()的时候!!!此时constructor的指向就会产生影响

来一个MDN上的列子:

function Parent() {};
function CreatedConstructor() {}

CreatedConstructor.prototype = Object.create(Parent.prototype);

CreatedConstructor.prototype.create = function create() {
  return new this.constructor();
}

new CreatedConstructor().create().create(); 

为什么报错,因为CreatedConstructor.prototype.constructor为Parent,所以new CreatedConstructor().create()的结果是Parent{}这个对象,这个对象没有create方法,所以报错了

解决办法:

function Parent() {}; 
function CreatedConstructor() {} 

CreatedConstructor.prototype = Object.create(Parent.prototype); 
CreatedConstructor.prototype.constructor = CreatedConstructor; // set right constructor for further using

CreatedConstructor.prototype.create = function create() { 
  return new this.constructor();
} 

new CreatedConstructor().create().create(); // it"s pretty fine

这时候需要重置CreatedConstructor的构造函数,使constructor重新指向自己

参考文章:JS constructor探讨(一):为什么要设置prototype.constructor?
Object​.prototype​.constructor

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/103611.html

相关文章

  • 源码之下无秘密 ── 做最好 Netty 源码分析教程

    摘要:背景在工作中虽然我经常使用到库但是很多时候对的一些概念还是处于知其然不知其所以然的状态因此就萌生了学习源码的想法刚开始看源码的时候自然是比较痛苦的主要原因有两个第一网上没有找到让我满意的详尽的源码分析的教程第二我也是第一次系统地学习这么大代 背景 在工作中, 虽然我经常使用到 Netty 库, 但是很多时候对 Netty 的一些概念还是处于知其然, 不知其所以然的状态, 因此就萌生了学...

    shenhualong 评论0 收藏0
  • ES6 探秘:Classes

    摘要:中的同名的实际上就是我们在的原型继承中使用的构造函数,所以中的是对中的构造函数的一种包装。我们发现,在中设定的属性被放在的构造函数中,而方法则以键值对的形式传入一个函数中。大家是不是对这种继承模式似曾相识呢对了,这就是所谓的构造函数窃取。 ES6中增加了一些新特性,但从底层的角度来说,只是一些语法糖。但是就我个人来说,如果不了解这些语法糖的本质,是用不安心的。那我们要如何揭开这些语法糖...

    caoym 评论0 收藏0
  • 用React写一个数字华容道,你需要知道秘密

    摘要:还在上班很无聊数字华容道畅玩地址开发源码地址这个叫前言年末了。光随机生成一个乱序数列是不够的,还得保证这个数列的逆序数为偶数,嗦嘎。所以,我们直接将交换的次数,记为数列逆序数个数,就达到了想要的效果。 还在上班?很无聊?数字华容道畅玩地址 开发源码地址 这个叫前言 年末了。哦,不,要过年了。以前只能一路站到公司的我,今早居然是坐着过来的。新的一年,总要学一个新东西来迎接新的未来吧,所以...

    Jason 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<