繁体   English   中英

JavaScript扩展类型返回

[英]JavaScript extending types return

我实际上在研究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什么意义?


工作示例#1

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


工作实例#2

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

今天下午我已经发了一封电子邮件给道格拉斯克罗克福德这个问题,他的答复是:

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|

让我试着解释一下。 我没有看过那本书,但道格拉斯·克罗克福德的JavaScript中经典继承有一个重要的句子,与关于Function.prototype.method的例子有关:

它返回这个。 当我编写一个不需要返回值的方法时,我通常会返回它。 它允许级联式编程。

实际上我对这个术语并不熟悉,我认为众所周知的术语是“ Fluent Interface ”或“Method Chaining”,阅读wiki页面,有不同语言的例子,所以你会理解它。

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对该模式的描述
PHP中的流畅接口
每周源代码14 - 流利的界面版 - 对我来说简短而且足以看到利弊(以及其他资源的链接)

我不明白你的要求,但是如果你不返回任何东西,你将不会给Function.prototype.method分配任何东西,这样的句子会让那句无用吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM