Javascript中的构造函数属性有好的用例吗?

Javascript中的构造函数属性有好的用例吗?,javascript,prototype-programming,Javascript,Prototype Programming,首先,这个问题不是“构造函数属性做什么?”——关于它到底是什么以及它是如何工作的,有很多很好的文档:它是对创建对象的函数的引用(可以从其原型继承) 我更感兴趣的是了解这个属性的常见用例。从理论上讲,这一切似乎都很好,但什么时候您真正需要对构建对象的函数的引用呢?以下是一些想法: 也许我想克隆它。我可以再次调用构造函数并 获取我的对象的另一个实例。这当然不行 因为您可能正在创建对象的 原型,而不是对象本身;再加上一种更受欢迎的方法 创建一个新对象并设置该对象的原型 也许您可以使用它来确定对象的“

首先,这个问题不是“构造函数属性做什么?”——关于它到底是什么以及它是如何工作的,有很多很好的文档:它是对创建对象的函数的引用(可以从其原型继承)

我更感兴趣的是了解这个属性的常见用例。从理论上讲,这一切似乎都很好,但什么时候您真正需要对构建对象的函数的引用呢?以下是一些想法:

  • 也许我想克隆它。我可以再次调用构造函数并
    获取我的对象的另一个实例。这当然不行 因为您可能正在创建对象的
    原型,而不是对象本身;再加上一种更受欢迎的方法 创建一个新对象并设置该对象的原型
  • 也许您可以使用它来确定对象的“类型” 是这似乎很奇怪,因为您可以使用
    instanceof

    Object.prototype.toString()
  • 您可以更改或重新分配构造函数吗?有没有一个好的理由 这样做

希望有些人能与一些使用构造函数引用的好JavaScript PARN相关联,或者提供一个关于该属性为什么存在的官方解释。

< P>一个很好的用例是“继承”和“JavaScript中的类”的实现。
// define the Person Class
function Person() {}

Person.prototype.walk = function(){
  alert ('I am walking!');
};
Person.prototype.sayHello = function(){
  alert ('hello');
};

// define the Student class
function Student() {
  // Call the parent constructor
  Person.call(this);
}

// inherit Person
Student.prototype = new Person();

// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;

// replace the sayHello method
Student.prototype.sayHello = function(){
  alert('hi, I am a student');
}

// add sayGoodBye method
Student.prototype.sayGoodBye = function(){
  alert('goodBye');
}

var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();

// check inheritance
alert(student1 instanceof Person); // true 
alert(student1 instanceof Student); // true
正如您所看到的,通过将
Student.prototype
重新分配给
new Person();
,我们继承了Person,但是我们需要将构造函数重新分配给Student,因为我们想要创建Student类的实例,而不是Person

更新

顺便说一句,javascript中更真实的继承示例是使用中间函数,因此在定义阶段不会创建Person对象:

// inherit Person
function F() {}
F.prototype = Person.prototype;
Student.prototype = new F();

我以前使用过它进行类型检查。它并不比
instanceof
有用多少,但它更明确一些

function isArray(o) {
    return o.constructor == Array;
}

构造函数属性很方便的一种情况是(如果它是可靠的话也会很方便),函数需要知道它所传递的参数的类型,例如

function foo(arg) {
  if ( /* if arg is an array */ ) {
    // deal with array
  } else if ( /* if arg is an object */ ) {
    // deal with object
  }
}
如果向上述函数传递了一个数组或对象,则在这两种情况下,
typeof
将返回object。构造函数属性可用于:

  if ( arg.constructor == Array )
但是,如果数组是在与测试发生位置不同的帧中创建的(即,它的数组构造函数是测试范围内数组函数的不同对象),则该操作将失败

因此,如果您排除了框架(或者范围是一个问题的其他情况),那么构造函数属性可以用于此


但这并不能解决构造函数属性可写(因此可以设置为任何内容)的一般问题以及原型链不仅仅是琐碎的情况。

Object.prototype.toString
不会帮助您确定通过用户定义构造函数创建的对象的类型。它只会帮助区分各种内置项。”这当然不能很好地工作,因为您可能会创建对象原型的实例,而不是对象本身”-你是什么意思?它工作得很好:实际上我甚至不知道您是如何做到的-类似于
var x=new myObj.constructor()
还是什么?@MikeChristensen是的,你可以这样做……这是一个合法的用例。哦,对不起,没有注意到你的JSFIDLE链接-我的意思是,是的,它在理论上确实有效(我没有试过),但你克隆的是原型,而不是对象。我已经更新了你的代码来演示:
Student.prototype=object.create(Person.prototype);
而不是
Student.prototype=新人();
。后一个是错误的,应该避免。我知道Javascript中基于原型的继承,但是在您的示例中,如果您注释掉
Student.prototype.constructor=Student;
,那么结果将完全相同。“更正”有什么意义"构造函数。我的问题是,你什么时候开始需要构造函数引用?@MikeChristensen,如果你没有正确的构造函数,那么你可能无法识别对象的确切类型:
student1.constructor==Student//如果没有分配正确的构造函数,那么它将为false
有意义吗?它似乎是这样的到目前为止,我们发现的唯一一个用例是,您需要能够准确地找出某个对象的类型,并且需要它跨基本类型和用户定义的类型工作。有时候,您甚至需要创建与现有对象相同的对象实例。唯一的方法是找出类型和类型n创建对象,或直接使用
obj.prototype.constructor
进行此操作。在这种情况下,最好测试
arg.constructor
arg.constructor.toString()
?当我只使用
数组
图像数据
时,JsHint会抱怨。问题在于找出JsHint抱怨的原因,以及它是否与您相关。Javascript非常动态,如果您设置边界并生活在其中,生活会更轻松。我从未找到测试
构造函数
属性的理由这样。如果我在进行类型测试,我通常会使用
instanceof
,因为它是内置于语言中的,即使对象继承了您正在测试的内容,也可以工作,即使
.constructor
设置不正确也可以工作。我想测试
.constructor
属性可以做的一件事就是测试叶对象类型是否正确匹配某种类型的对象,但大多数多态设计不需要知道这一点。如果它像“鸭子”一样工作,那么你可以像“鸭子”一样对待它,即使它被子类化为“绿头鸭”。