我实际上在研究Crockford的 Javascript:好的部分。我是JavaScript的新手,所以我很难理解这段代码的工作原理:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
以下是我的想法:
作为一个方法(对象内部的一个函数),this
指向Function
对象,但为什么需要返回该对象,因为我从方法内部访问它?如果我是对的,this
是参考,而不是本地副本,所以:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
};
应该也可以。
另一方面,在JavaScript中,没有return语句的函数返回undefined
并将其分配给Function.prototype.method
。
返回this
有什么意义?
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
var add = function(a, b) {
return a+b;
};
Function.method('add', add);
var f = function() {};
print(f.add(1,2));
Number.method('integer', function () {
return Math[this < 0 ? 'ceil' : 'floor'](this);
});
print((-10/3).integer());
输出:
-3 3
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
};
var add = function(a, b) {
return a+b;
};
Function.method('add', add);
var f = function() {};
print(f.add(1,2));
Number.method('integer', function () {
return Math[this < 0 ? 'ceil' : 'floor'](this);
});
print((-10/3).integer());
输出:
-3 3
答案 0 :(得分:5)
今天下午我已经发送了一封电子邮件给Douglas Crockford这个问题,他的答复是:
我不是在开玩笑。这是他写的唯一的事情。F.method的(a)。方法(b)中。方法(c)中
无论如何,我个人对他(隐秘)答案的解释是创建链方法:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this; //This returns the same Function object into the chain below
};
var add = function (a, b) { return a+b; };
var sub = function (a, b) { return a-b; };
var mul = function (a, b) { return a*b; };
var div = function (a, b) { return a/b; };
Function.method('add', add).method('sub', sub).method('mul', mul).method('div', div);
也就是说,不是一次使用一个行创建新方法,而是可以重新应用链中的下一个方法之前,Function
。
在此示例中,链从从左到右:
|Function|--method-->|add|--returns-->|Function|--method-->|sub|--returns-->|Function|--method-->|mul|--returns-->|Function|--method-->|div|-->returns-->|Function|
答案 1 :(得分:5)
让我试着解释一下。我没有看过那本书,但道格拉斯·克罗克福德的一篇文章Classical Inheritance in JavaScript有一个重要的句子,与关于Function.prototype.method的那个例子有关:
它返回此。当我写一个方法 我不需要返回一个值 通常让它归还。它允许 对于级联式的编程。
实际上我对这个术语并不熟悉,我认为众所周知的术语是“Fluent Interface”或“方法链”,阅读维基页面,有不同语言的例子,所以你会理解它。
PS。 @Gianluca Bargelli以这种方式提供使用Function.prototype.method的例子有点快,所以我不在我的回答中发布
ADDON:如何根据您的示例使用它:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
}
Number.method('integer', function () { // you add 'integer' method
return Math[this < 0 ? 'ceil' : 'floor'](this);
})
.method('square', function () { // you add 'square' method with help of chaining
return this * this;
});
console.info( (-10/3).integer().square() ); // <- again chaining in action
你看,integer()返回Number对象,所以你可以调用另一个方法,而不是写:
var a = (-10/3).integer();
console.info( a.square() );
关于我使用它的方式几句话,大多数时候我更喜欢写“每个方法 - 带缩进的新行,对我来说这种方式更具可读性:
Function.method('add', add)
.method('sub', sub)
.method('mul', mul)
.method('div', div);
通过这种方式,我看到了我的起点,“新行/缩进”告诉我,我仍然会修改该对象。将它与长线比较:
Function.method('add', add).method('sub', sub).method('mul', mul).method('div', div);
或典型方法:
Function.method('add', add);
Function.method('sub', sub);
Function.method('mul', mul);
Function.method('div', div);
ADDON2:我在处理实体时通常使用这种方法(Fluent界面模式),例如Java代码:
public class Person {
private String name;
private int age;
..
public String getName() {
return this.name;
}
public Person setName( String newName ) {
this.name = newName;
return this;
}
public int getAge() {
return this.age;
}
public Person setAge( int newAge ) {
this.age = newAge;
return this;
}
..
}
它允许我以简单的方式构造Person
对象:
Person person = new Person().setName("Leo").setAge(20);
有些人对它有所不同,他们为set
/ get
添加了新方法,并称之为with
:
public class Person {
private String name;
private int age;
..
public String getName() {
return this.name;
}
public void setName( String newName ) {
this.name = newName;
}
public Person withName( String newName ) {
this.setName( newName ); // or this.name = newName; up to you
return this;
}
public int getAge() {
return this.age;
}
public void setAge( int newAge ) {
this.age = newAge;
}
public Person withAge( int newAge ) {
this.setAge( newAge ); // or this.age = newAge; up to you
return this;
}
..
}
现在我的上一个示例如下:
Person person = new Person().withName("Leo").withAge(20);
这样我们就不会改变set方法的含义(我的意思是我们不会增强它,所以它可以像大多数开发人员所期望的那样工作......至少人们不希望set
方法可以返回什么;))。关于这些特殊方法的一个有趣的事情 - 它们可以放松自我记录,但是当你使用它们时它们会提高可读性(例如Person
创建的例子,withName
非常清楚我们究竟在做什么。
阅读更多:
FluentInterface - Martin Fowler对该模式的描述
Fluent Interfaces in PHP
The Weekly Source Code 14 - Fluent Interface Edition - 至于我的简短和足够好,可以看到利弊(以及其他资源的链接)
答案 2 :(得分:0)
我不明白你的要求,但是如果你没有返回任何东西,你将不会给Function.prototype.method分配任何东西,那么你觉得这句话没用了吗?