如何在不更改为新对象的情况下设置对象的构造函数

How to set the constructor of an Object without changing to a new Object?

本文关键字:对象 情况下 构造函数 设置 新对象      更新时间:2023-09-26

在这个相关的问题中,设置构造函数的答案是这样的:

function OldClass() {
    alert("old class with incomplete constructor")
}
function ChangedClass(){
    alert('new class with same prototype and more complete constructor');
}
ChangedClass.prototype = OldClass.prototype;
var theClassIWant = new ChangedClass();

这并不是真正设置构造函数,而是创建一个新对象并继承原型。如何在不更改为新对象的情况下设置对象的构造函数?有可能吗?

附言:我想要这样的东西:

//non working code
var Foo = function() {}
Foo.prototype.constructor = function(bar_val) {
    this.bar = bar_val;
}
var fez = new Foo("cat")
console.log(fez.bar); // outputs: cat;

constructor是构造函数的prototype属性,默认情况下指向函数本身。

修改Foo.prototype.constructor时,此属性指向另一个函数。但是,构造函数Foo仍然存在。因此,当您创建一个对象时,您仍然实例化构造函数Foo,而不是Foo.prototype.constructor指向的那个。

这就是您的代码无法工作的原因。然后让我们谈谈为什么我们需要更改构造函数以及如何更改。

在ES5及之前的版本中,我们利用原型来模拟类继承机制。看起来像这样:

// parent class
function Person(name) {
  this.name = name
}
// define parent method
Person.prototype.say = function() {
  console.log(this.name)
}
// child class
function Coder(name, major) {
  Person.call(this, name) // inherits parent properties
  this.job = 'Coding'
  this.major = major
}
// inherits properties and methods from parent prototype
Coder.prototype = new Person()
// define child method
Coder.prototype.work = function() {
  console.log('I write ' + this.major)
}
// instantiate a child object
var me = new Coder('Leo', 'JavaScript')
console.log(me) // {name: "Leo", job: "Coding", major: "JavaScript"}

一切看起来都很完美,但有一个问题:

console.log(me.constructor) // Person

什么?me不是用Coder构造的吗?为什么?

回到这个答案的第一行,再读一遍:constructor是构造函数的prototype属性

最初Coder.prototype.constructor本身就是Coder。但有了这条线:Coder.prototype = new Person(),它就变了。Coder.prototype.constructor现在等于Person.prototype.constructor,即Person

有人会说,试试instanceof。是的,有效:

me instanceof Coder // true

但它也是Persontrue,因为Coder是它的一个子类:

me instanceof Person // true

这没有意义,所以我们需要解决构造函数的问题。这就是为什么我们在Coder.prototype = new Person()之后使用Coder.prototype.constructor = Coder,以获取原始构造函数。

完整代码如下:

// parent class
function Person(name) {
  this.name = name
}
Person.prototype.say = function() {
  console.log(this.name)
}
// child class
function Coder(name, major) {
  Person.call(this, name) // inherits parent class
  this.job = 'Coding'
  this.major = major
}
Coder.prototype = new Person() // inherits parent's prototype
Coder.prototype.constructor = Coder // get back constructor
Coder.prototype.work = function() {
  console.log('I write ' + this.major)
}
myClass = {
  constructor: function(text){
  console.log(text);
 }
}
let ob = Object.create(myClass);
ob.constructor("old constructor "); //Output: old constructor
myClass.constructor = function(){
 console.log("new constructor ")
}
ob.constructor(); //Output: new constructor

可以对类的每个属性或函数执行此操作。

请在此处观看此视频。它完美地解释了这一点。

相关文章: