如何设置Object的构造函数而不更改为新的Object?

时间:2016-11-02 06:31:36

标签: javascript constructor prototype

this related question中,设置构造函数的答案是这样的:

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();

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

P.S。我想要这样的东西:

//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;

2 个答案:

答案 0 :(得分:2)

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

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

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

在ES5和之前,我们利用prototype来模拟一个类继承机制。看起来像这样:

// 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

什么?是不是meCoder构建的?为什么呢?

返回到此答案的第一行,再次阅读:constructor是构造函数prototype属性

原来Coder.prototype.constructor本身就是Coder。但是使用这一行:Coder.prototype = new Person(),它已经改变了。 Coder.prototype.constructor现在等于Person.prototype.constructor,即Person

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

me instanceof Coder // true

true也是Person,因为Coder是它的子类:

me instanceof Person // true

这没有意义所以我们需要修复构造函数问题。这就是我们在Coder.prototype.constructor = Coder之后使用Coder.prototype = new Person()来恢复原始构造函数的原因。

完整代码如下所示:

// 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)
}

答案 1 :(得分:1)

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

您可以对班级的每个属性或功能执行此操作。

观看此视频here。它完美地解释了它。