什么';是JavaScript中类型特定扩展方法的等价物吗?
假设你有一个class什么';是JavaScript中类型特定扩展方法的等价物吗?,javascript,arrays,prototype,extension-methods,type-safety,Javascript,Arrays,Prototype,Extension Methods,Type Safety,假设你有一个class人。其定义如下: function Person(name, age) { this.name = name; this.age = age; } 现在假设你有一个人的数组(或人),你想找到最老的一个。在C#中,您可以通过扩展方法执行此操作: Person Oldest(this IEnumerable<Person> people) => people.OrderByDescending(p => p.Age).First
人
。其定义如下:
function Person(name, age) {
this.name = name;
this.age = age;
}
现在假设你有一个人的数组
(或人),你想找到最老的一个。在C#中,您可以通过扩展方法执行此操作:
Person Oldest(this IEnumerable<Person> people) =>
people.OrderByDescending(p => p.Age).First();
// Usage:
var elder = people.Oldest();
这很好,语法与C#相同,但有一些缺点:
1) 它修改了内置的原型,这可能会导致与其他这样做的库发生冲突
2) 它不是类型安全的:很容易意外调用不包含人员的数组,这可能导致运行时错误
或者,您可以这样定义它:
function oldest(people) {
// ...
}
但是你必须像oldest(people)
那样调用它,而不是people.oldest()
,这会妨碍可读性
在JavaScript中是否有我所缺少的类型安全、语法上“好”的方法来实现这一点?您可以尝试不同的方法:
- 如果程序中只有一个
s数组,则可以将该方法添加为数组的自有属性Person
var people = [person1, person2]; people.oldest = function() { // Find the oldest person in this array }; // ... later people.oldest();
- 您可以将方法定义为
的静态属性,并将Person
的数组作为参数传递:Person
Person.oldest = function(people) { // Find the oldest person in an array }; var people = [person1, person2]; Person.oldest(people);
- 扩展
(需要ES6)阵列
- 如果程序中只有一个
s数组,则可以将该方法添加为数组的自有属性Person
var people = [person1, person2]; people.oldest = function() { // Find the oldest person in this array }; // ... later people.oldest();
- 您可以将方法定义为
的静态属性,并将Person
的数组作为参数传递:Person
Person.oldest = function(people) { // Find the oldest person in an array }; var people = [person1, person2]; Person.oldest(people);
- 扩展
(需要ES6)阵列
最老的(人)
只需将其视为一种装饰模式——一种将功能投射到一组未知的相关实体中的合法方法
然后-您可以在函数中执行类型检查
您可以名称空间使用它使语法更加“明显”,如果这是您关心的问题,我想:
personList(persons).getOldest()
作为一个客观的例子
然后,您可以将特定于类型的检查添加到creator for personList:
function personList(persons) {
//iterate over persons and make sure
//it's valid. return undefined or {} if not.
return {
getOldest: function() {
// insert clever code here ...
persons.slice().dice().puree();
},
getYoungest: function() {
//even more clever code here ...
}
}
}
通过这种方法,代码
PersonList(cats).getOldest()
通过抛出一个“GetOlestUndefined”错误——当您有11000000行js代码要排序时,可以很容易地发现问题
它还有一个额外的优点,就是让你的c#内部孩子感觉更自在(在你的项目文件夹中有一个名为“ArrayExtensions.Persons.js”的js文件)。感觉像是“c#soul鸡汤”,对吧?因为js不是类型安全的,所以最好以
最老的(人)
的身份实现该方法
只需将其视为一种装饰模式——一种将功能投射到一组未知的相关实体中的合法方法
然后-您可以在函数中执行类型检查
您可以名称空间使用它使语法更加“明显”,如果这是您关心的问题,我想:
personList(persons).getOldest()
作为一个客观的例子
然后,您可以将特定于类型的检查添加到creator for personList:
function personList(persons) {
//iterate over persons and make sure
//it's valid. return undefined or {} if not.
return {
getOldest: function() {
// insert clever code here ...
persons.slice().dice().puree();
},
getYoungest: function() {
//even more clever code here ...
}
}
}
通过这种方法,代码
PersonList(cats).getOldest()
通过抛出一个“GetOlestUndefined”错误——当您有11000000行js代码要排序时,可以很容易地发现问题
它还有一个额外的优点,就是让你的c#内部孩子感觉更自在(在你的项目文件夹中有一个名为“ArrayExtensions.Persons.js”的js文件)。感觉像是“灵魂鸡汤”,对吧?另一种分类原型方法
Person.prototype.ageCompare
检查参数是否为Person
的实例,如果不是,则抛出错误
职能人员(姓名、年龄){
this.name=名称;
这个。年龄=年龄;
}
Person.prototype.ageCompare=函数(b){
如果(!(b个人实例)){
抛出“b不是人的实例!”;
}
返回this.age-b.age;
};
var peoples=[新人('Tim',31),新人('Jane',32),新人('Frank',28),新人('Sue',31),新人('Baby',2)];
排序(函数(a,b){返回a.ageCompare(b);});
document.write(''+JSON.stringify(peoples,0,4)+'')代码>另一种带有排序原型的方法Person.prototype.ageCompare
检查参数是否为Person
的实例,如果不是,则抛出错误
职能人员(姓名、年龄){
this.name=名称;
这个。年龄=年龄;
}
Person.prototype.ageCompare=函数(b){
如果(!(b个人实例)){
抛出“b不是人的实例!”;
}
返回this.age-b.age;
};
var peoples=[新人('Tim',31),新人('Jane',32),新人('Frank',28),新人('Sue',31),新人('Baby',2)];
排序(函数(a,b){返回a.ageCompare(b);});
document.write(''+JSON.stringify(peoples,0,4)+'')
我只需要使用最老的(人)
并返回最老的人,简单且安全,而且在我看来比为最老的人分配新属性可读性好得多。对于最老的人,它不需要排序,只需迭代并返回具有最大值的集合。排序是n log n
。argmax可以线性完成。只需从头到尾迭代。我只需使用最老的(人)
并返回最老的人,简单且安全,而且在我看来比为最老的人分配新属性可读性好得多。对于最老的人,不需要排序,只需迭代并返回具有最大值的集合。排序是n log n
。argmax可以线性完成。从开始到结束只需迭代。嗯,我喜欢Person.oldest()
的想法。使事情更有条理。嗯,我喜欢Person.oldest()
的想法。使事情更有条理。