克罗克福德书中的“方法”方法:Javascript:The Good Parts

时间:2010-10-19 09:23:55

标签: javascript methods

道格拉斯·克罗克福德在他的书(第4页)中写道:

在整本书中,method方法用于定义新方法,这是它的定义:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

然后他开始使用此methodNumber, String, Function, Object, Array, RegExp中添加方法,以下是完整列表:

P33:

Number.method('integer', function () {...});
String.method('trim', function () {...});

P40(不确定页面41中是否存在印刷错误:结束()):

String.method('deentityify', function () {...}());

P43& P44:

Function.method('curry', function () {...});

P47(我在这里很困惑,不知道为什么Crockford定义new方法,而且他似乎从不在书中使用new方法):

Function.method('new', function () {...});

P48:

Function.method('inherits', function (Parent) {...});

P54:

Object.method('superior', function (name) {...});

P62:

Array.method('reduce', function (f, value) {...});

P79:

Array.method('pop', function () {...});
Array.method('push', function () {...});
Array.method('shift', function () {...});

P82:

Array.method('splice', function (start, deleteCount) {...});

P84:

Function.method('bind', function (that) {...});

P88:

RegExp.method('test', function (string) {...});
String.method('charAt', function (pos) {...});

P90(不确定页面91中是否存在印刷错误:结束()):

String.method('entityify', function () {...}());

定义method基于Function,为什么Number, String, Object, Array, RegExp除了Function之外可以使用它?这个{{1}用于其他数据类型?

另一个小问题:第63页& 64,method的定义没有使用上面Array.dim, Array.matrix, Array.identity,为什么?

4 个答案:

答案 0 :(得分:22)

JavaScript中的所有本机函数都继承自Function.prototypeNumberStringObjectArrayRegExp都是函数,因此它们继承自Function.prototype

method旨在调用构造函数。它的工作是将您提供给它的函数变成一个方法,该方法存在于由您调用method的构造函数创建的每个对象上。您会注意到在Crockford传递给method的函数中,他使用this,它是对调用该方法的对象的引用。 Array.dimArray.matrixArray.identity不使用this,因为它们独立于任何特定数组运行,因此不需要是单个数组对象的方法。为方便起见,它们被指定为Array函数的属性:它们同样可以作为全局范围内的函数自行存在。

答案 1 :(得分:4)

另外,在P40上:

end()表示“使用此函数返回的函数”,而不是返回它的外部函数。

如果他离开了final(),对deentityify的调用会返回一个函数,而不是一个字符串。

用道格拉斯·克罗克福德自己的话来说:

  

我们立即调用我们刚刚创建的函数   使用()运算符。该调用创建并返回该函数   这成为了深化方法。

答案 2 :(得分:3)

@Tim Down给出的解决方案是准确的,但并不完全清楚。

  

功能对象与功能实例对象

首先,在javascript中,函数也是一个对象。从这里,我的意思不是new()构造创建的对象,而是函数本身。为了避免混淆,我将这些对象称为 Function object ,并将使用new()构造函数创建的对象称为 Function instance object

  

_ proto _和原型属性

javascript中的任何函数对象都有两个属性: _ proto _ prototype 。此外,任何 Function实例对象(使用新构造函数创建)都具有属性 _ proto _ _ proto _ 是定义继承的原因。

可以找到一些好的资源

http://zeekat.nl/articles/constructors-considered-mildly-confusing.html

  

如何定义继承?

如果objA和objC通过任意数量的 _ proto _ 连接,则对象objA继承另一个对象objC。因此,如果objA的 _ proto _ 等于objB,并且objB的 _ proto _ 等于objC,则objA继承objB和objC,而objB继承objC。

  

继承是什么意思?

这意味着任何继承对象都可以使用继承对象的任何属性。

  

什么是Function.prototype

每个功能对象 _ proto _ 所引用的对象。这意味着每个 Function对象都可以访问Function.prototype的属性,因为每个 Function对象都继承了Function.prototype对象。这也意味着如果将方法属性添加到Function.prototype对象,它将可用于javascript中所有可能的 Function对象。这包括字符串,数字等

  

this.prototype [name] = func;

这指的是功能对象当'方法'从函数对象调用,如Number,String等。这意味着我们现在在 Function对象中有一个名为" name"的新属性,它的功能' func'。

  

功能对象的原型属性有什么用处

功能对象 原型功能实例对象引用 _ proto _ 使用该函数的新构造创建。

如果执行以下操作:

  

Number.method('整数',function(){...});

然后Number.prototype中定义了整数方法。这意味着每个Number 函数实例对象,例如新号码(2.4),将"继承"这个新属性'整数'来自Number.prototype,因为Number 函数实例对象将其 _ proto _ 设置为Number.prototype。

答案 3 :(得分:0)

尝试使用这种原型方法:

String.prototype.deentityify = function () { ... }

然后:

document.writeln('<">'.deentityify( ));

我们可以看到: <">