为什么把成员添加到构造函数而不是Prototype中?

Why add members to Constructor function and not to Prototype?

本文关键字:Prototype 构造函数 成员 添加 为什么      更新时间:2023-09-26

为什么要将成员添加到构造函数而不是原型中?

function foo() {
}
foo.prototype.isThereSayShoeSize = function() {
    console.log(this.sayShoeSize);
}
foo.fooObject = {num: 100, shoeSize: 43}
foo.sayShoeSize = function() {
    console.log(foo.fooObject.shoeSize)
}
var myFoo = new foo();
console.log(myFoo.sayShoeSize);  //undefined
myFoo.isThereSayShoeSize()       //undefined

成员不为实例所有,也不为实例间共享。因此,这些成员不能通过instance.member语法访问,也不能在实例中使用this关键字访问。

因此,添加到构造函数中的成员似乎与类型没有关系。

我只能想到两种可能的解释。通过将这些成员与类型分组来节省名称空间,如果这些成员与类型无关,那么这样做就没有多大意义。它们是静态成员,可以在没有类型实例的情况下访问。如果有其他类型的对象希望使用这些成员,这是有意义的。但是在我看到这种模式的上下文中,这些成员仅由它们所附加的类型的实例使用。因此,在这种情况下,它们与类型相关并且只由类型的实例使用,那么为什么不将它们放在原型中呢?

我对此有点困惑,你可能会说。我认为,也许这种向构造函数添加成员的模式在我所看到的上下文中是不合适的,成员应该被添加到原型中。但你认为这些成员是静态的吗?让成员既可以被其所连接的类型消费,也可以被其他类型消费,这是这种模式的主要用途吗?

当你这样做的时候:

function foo() {};
foo.fooObject = {num: 100, shoeSize: 43};

它类似于在c++世界中设置一个类变量,所有实例都可以使用它作为foo.fooObject,并且所有实例都是相同的。这是一种设置全局变量的命名空间方式。正如您所指出的,它们不是实例变量,所以这种技术应该只在需要一个有作用域的全局变量时使用。

基本上有静态方法和属性。

为什么?如何?

让我们忘记foo是用来作为构造函数的。添加到foo的方法是foo()函数的成员(函数也是对象,所以它们也可以有方法)

因此,要调用这些方法,您只需访问foo函数的成员。这意味着要么

foo.sayShoeSize();

foo['sayShoeSize']();
此时,您不必使用new操作符调用foo。由于没有原型链的一部分,使用foo作为构造函数创建的对象将不会继承这些方法和属性。这意味着:
var myFoo = new foo();
console.log(typeof myFoo.sayShowSize); // undefined

总而言之,直接在构造函数上定义的函数不应该使用或依赖this。换句话说,this将被绑定到全局对象(当然,除非使用apply或call调用它们)