【问题标题】:"method" method in Crockford's book: Javascript: The Good PartsCrockford 书中的“方法”方法:Javascript: The Good Parts
【发布时间】:2011-04-27 09:16:21
【问题描述】:

Douglas Crockford 在他的书(第 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页是否有错字:end ()):

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页是否有错字:end ()):

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

method的定义是基于Function,为什么除了Function之外还可以在Number, String, Object, Array, RegExp中使用?而这个method可以用于其他数据类型吗?

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

【问题讨论】:

    标签: javascript methods


    【解决方案1】:

    示例:如果有人卡住了,Currying 可以重写如下。见jsFiddle demo

     Function.prototype.curry = function ( ) {
     var slice = Array.prototype.slice;
     var args = slice.apply(arguments);
     var that = this; 
     return function () {  
        return that.apply(null,args.concat (slice.apply(arguments)));
     }
    };
    var add = function(a, b)
    {
        return a + b;
    }
    var add1 = add.curry(1);
    document.writeln(add1(6)); // 7
    

    【讨论】:

      【解决方案2】:

      尝试使用这个原型方法:

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

      然后:

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

      我们可以看到: <">

      【讨论】:

        【解决方案3】:

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

        函数对象与函数实例对象

        首先,在javascript中,函数也是对象。由此,我的意思不是由 new () 构造创建的对象,而是函数本身。为避免混淆,我将此类对象称为 Function object,将使用函数的 new () 构造创建的对象称为 Function instance object

        _proto_和原型属性

        javascript中的任何函数对象都有两个属性:_proto_prototype。此外,任何函数实例对象(使用新构造函数创建)都有一个属性 _ 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;

        this 指的是 Function 对象,当“方法”从 Function 对象s(如 Number、String 等)调用时。这意味着我们现在在函数对象,名称为“name”,其函数为“func”。

        Function object

        prototype属性有什么用

        函数对象原型函数实例对象_proto_引用使用该函数的新构造创建。

        如果执行了以下操作:

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

        然后 Number.prototype 在其中定义了 integer 方法。这意味着每个 Number 函数实例对象,例如new Number (2.4),将从 Number.prototype 中“继承”这个新属性 'integer',因为 Number function instance object 将其 _ proto _ 设置为 Number .prototype。

        【讨论】:

          【解决方案4】:

          顺便说一句,在 P40:

          end() 的意思是“使用这个函数返回的函数”,而不是返回它的外部函数。

          如果他没有结束最后的 (),对 deentityify 的调用将返回一个函数,而不是一个字符串。

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

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

          【讨论】:

            【解决方案5】:

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

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

            【讨论】:

            • 我不确定数字、字符串、对象、数组、正则表达式(可能还有函数和日期以及布尔值)是否都是函数。看来它们是全局对象。
            • @John:我向你保证,它们都是函数。如果您不相信我,请尝试alert(typeof Number) 等,或查看规范(第 15.1.4 节):ecma-international.org/publications/standards/Ecma-262.htm。它们也是全局对象的属性,如果这就是你的意思的话。
            • @John:我明白了,你已经在developer.mozilla.org/en/JavaScript/Reference/Global_Objects 上查看了 Mozilla 的文档。正确的是,除了作为函数之外,NumberStringObject 等也是对象,因为所有函数都是对象;确实,作为全局对象的属性,它们在全局范围内可用,因此可以描述为“全局对象”。然而,鉴于官方定义的术语“全局对象”的存在,我发现 Mozilla 对术语“全局对象”的使用没有帮助。
            • 谢谢!你甚至知道我有这个问题的原因。我不能很好地理解 Mozilla 的术语“全局对象”,也许这是我在 SO 中的下一个问题。
            • 那么为什么我不能在节点 5.2.0 中运行这些?我得到一个 String.method is not a function 错误
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-07-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多