Javascript中的构造函数属性是否有一个很好的用例?

时间:2011-11-10 01:08:50

标签: javascript prototype-programming

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

我对了解此属性的常见用例更感兴趣。它在理论上似乎都很好,但是什么时候你实际上需要对构造你的对象的函数的引用?一些想法是:

  • 也许我想要克隆它。我可以再次调用构造函数和
    获取我的对象的另一个实例。这当然不会很好 因为您可能正在创建对象的实例 原型,而不是对象本身;加上一个更受欢迎的方法 是创建一个新对象并设置该对象的原型。
  • 也许你可以用它来弄清楚对象的“类型” 是。这似乎很奇怪,因为你可以使用instanceof或 而是Object.prototype.toString()
  • 您可以更改或重新分配构造函数吗?是否有充分的理由 这样做?

希望有些人可以使用构造函数引用的一些好的Javascript模式,或提供有关属性存在的官方解释。

3 个答案:

答案 0 :(得分:4)

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

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 )

但如果数组是在与测试发生的不同的帧中创建的(即,它的Array构造函数是测试范围内Array函数的不同对象),则会失败。

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

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

答案 1 :(得分:3)

一个很好的用例是在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类的实例,但不是人

<强>更新

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

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

答案 2 :(得分:1)

我之前用过它进行类型检查。它比instanceof更有用,但它更明确一些。

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