Node.js 猫鼬';静态';方法与&x27;实例';方法
我相信这个问题类似于,但术语不同。从猫鼬4: 我们也可以定义自己的自定义文档实例方法 现在,我们所有的动物实例都有一个findSimilarTypes方法可用 然后: 向模型中添加静态方法也很简单。继续我们的动物模式:Node.js 猫鼬';静态';方法与&x27;实例';方法,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我相信这个问题类似于,但术语不同。从猫鼬4: 我们也可以定义自己的自定义文档实例方法 现在,我们所有的动物实例都有一个findSimilarTypes方法可用 然后: 向模型中添加静态方法也很简单。继续我们的动物模式: 似乎对于静态方法,每个动物实例都有可用的findByName方法。模式中的静态和方法对象是什么?区别是什么?为什么我要使用一种方法而不是另一种方法?statics是在模型上定义的方法方法在文档(实例)上定义 您可以使用static方法,如Animal.findByName: co
似乎对于静态方法,每个动物实例都有可用的
findByName
方法。模式中的静态
和方法
对象是什么?区别是什么?为什么我要使用一种方法而不是另一种方法?statics
是在模型上定义的方法<代码>方法在文档(实例)上定义
您可以使用static方法,如Animal.findByName
:
const fido = await Animal.findByName('fido');
// fido => { name: 'fido', type: 'dog' }
您可以使用一个实例方法,比如fido.findSimilarTypes
:
const dogs = await fido.findSimilarTypes();
// dogs => [ {name:'fido',type:'dog} , {name:'sheeba',type:'dog'} ]
但是你不会做Animals.findSimilarTypes()
,因为动物是一个模型,它没有“类型”findSimilarTypes
需要一个this.type
,该类型在动物模型中不存在,只有文档实例才会包含该属性,如模型中定义的那样
类似地,您也不会执行fido.findByName
,因为findByName
需要搜索所有文档,而fido
只是一个文档
当然,从技术上讲,您可以,因为实例确实可以访问集合(或
this.model('Animal')
),但拥有一个不使用实例中任何属性的实例方法是没有意义的(至少在本例中是如此)。(感谢您指出这一点)数据库逻辑应该封装在数据模型中。Mongoose提供了两种方法,方法和静态。方法向文档中添加实例方法,而静态向模型本身添加静态“类”方法。static关键字为模型定义静态方法。静态方法不会在模型实例上调用。相反,它们在模型本身上被调用。这些通常是实用程序函数,例如用于创建或克隆对象的函数。如下例:
const bookSchema = mongoose.Schema({
title: {
type : String,
required : [true, 'Book name required']
},
publisher : {
type : String,
required : [true, 'Publisher name required']
},
thumbnail : {
type : String
}
type : {
type : String
},
hasAward : {
type : Boolean
}
});
//method
bookSchema.methods.findByType = function (callback) {
return this.model('Book').find({ type: this.type }, callback);
};
// statics
bookSchema.statics.findBooksWithAward = function (callback) {
Book.find({ hasAward: true }, callback);
};
const Book = mongoose.model('Book', bookSchema);
export default Book;
更多信息:对我来说,这并不意味着在“static”或“instance”关键字前面添加Mongoose来添加任何东西 我相信静态的意义和目的在任何地方都是一样的,即使对于一种外来语言或某种驱动程序来说也是一样的,它像另一种面向对象编程一样表示构建块的模型。例如,情况也是如此 来自维基百科: 面向对象编程(OOP)中的方法是与消息和对象关联的过程。对象由数据和行为组成。数据和行为包括一个接口,该接口指定对象的各种消费者[1]如何使用该对象 数据表示为对象的属性,行为表示为对象的方法。例如,窗口对象可以有打开和关闭等方法,而其状态(无论在任何给定时间点打开还是关闭)将是一个属性 静态方法意味着与类的所有实例相关,而不是与任何特定实例相关。从这个意义上讲,它们类似于静态变量。一个例子是一个静态方法,它将类的每个实例的所有变量的值相加。例如,如果有一个产品类,它可能有一个静态方法来计算所有产品的平均价格 数学最大值(双a,双b) 此静态方法没有所属对象,并且不在实例上运行。它接收来自其参数的所有信息。[7] 即使不存在该类的实例,也可以调用静态方法。静态方法称为“静态”,因为它们是在编译时根据调用它们的类进行解析的,而不是像实例方法那样动态解析的,实例方法是根据对象的运行时类型进行多态解析的
- 对
静态方法使用
.statics
- 对
实例
方法使用
.methods
静态
与方法几乎相同,但允许定义直接存在于模型上的函数
静态方法
属于模型,方法
属于实例静态方法
适用于定义它们的整个模型,而实例方法
仅适用于集合中的特定文档
this
在静态方法的上下文中返回整个模型,而this
在实例方法的上下文中返回文档
比如说:
const pokemon=newmongoose.Schema({})
pokemon.statics.getAllWithType=函数(类型){
//查询整个模型并查找口袋妖怪
//同类型
//this.find({type:type})
}
pokemon.methods.sayName=函数(){
//说出一个特定口袋妖怪的名字
//console.log(this.name)
}
const pokemonModel=mongoose.model('schema',pokemon)
const squirtle=new pokemonModel({name:“squirtle”})
//从模型中获取所有水型口袋妖怪[静态方法]
pokemonModel.getAllWithType(“水”)
//让squirtle说出它的名字[实例方法]
squirtle.sayName()
@laggingreflect您的第二条评论不正确。您可以使用fido.findByName
,因为fido
确实可以访问整个集合(通过this.model('Animal')
)。但是,拥有一个不使用任何属性的实例方法没有多大意义
const dogs = await fido.findSimilarTypes();
// dogs => [ {name:'fido',type:'dog} , {name:'sheeba',type:'dog'} ]
const bookSchema = mongoose.Schema({
title: {
type : String,
required : [true, 'Book name required']
},
publisher : {
type : String,
required : [true, 'Publisher name required']
},
thumbnail : {
type : String
}
type : {
type : String
},
hasAward : {
type : Boolean
}
});
//method
bookSchema.methods.findByType = function (callback) {
return this.model('Book').find({ type: this.type }, callback);
};
// statics
bookSchema.statics.findBooksWithAward = function (callback) {
Book.find({ hasAward: true }, callback);
};
const Book = mongoose.model('Book', bookSchema);
export default Book;
//instance method
bookSchema.methods.findByType = function (callback) {
return this.model('Book').find({ type: this.type }, callback);
};
// static method
bookSchema.statics.findBooksWithAward = function (callback) {
Book.find({ hasAward: true }, callback);
};