検索

ホームページ  >  に質問  >  本文

请教我对《javascript语言精粹》一书中“给类型增加方法”的困惑?

以下代码摘自《javascript语言精粹》4.7节(P32),为了方便测试我略微修改了下代码:

<!DOCTYPE HTML>
<html lang="en-US">
<script type="text/javascript">
window.onload = function () {
    Function.prototype.method = function (name,func) {
        this.prototype[name] = func;
        return this;
     };
    Number.method('integer', function () {
        return Math[this < 0 ? 'ceil' : 'floor'](this);
    });

    var simple = document.getElementById('simple');
    var outputInt = (-10/3).integer();
    simple.innerHTML = outputInt;
}
</script>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>一些无关紧要的内容
<p id="simple">这里应该是一个测试数字</p>
</body>
</html>

我的困惑:
Number.method()这个方法是在什么地方定义的呢?或者说可不可以这么理解:Number下没有method()方法,于是Number.method()实际上查找的是Number.prototype.method(),如果是第二个假设的话,那么Number.prototype.method()又是在什么地方定义的呢?
第一个函数定义的可是Function.prototype.method()的呀?我把第一个函数换成Object.prototype.method()也是好使的,但是换成其他的关键字就不好使了,例如Number.prototype.method()就不好使了,这是为什么呢?难道说这里的Object包含Function?如果真的是包括的话,那它和typeof的object值不包含 function值,如何区分?
我知道ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String,那么Function.prototype.method中的Function是什么?应该怎么称呼?我需要搜索什么关键字才能学习到相关的知识点?

PHPzPHPz2790日前814

全員に返信(4)返信します

  • 数据分析师

    数据分析师2017-10-01 01:16:02

    書籍「JavaScript 言語のエッセンス」の「型へのメソッドの追加」に関する私の混乱について教えてください。 -PHP中国語サイトQ&A-書籍「JavaScript言語エッセンス」の「型へのメソッドの追加」についての混乱について教えてください。 -PHP中国語サイトQ&A

    ぜひ見て学んでください。

    返事
    0
  • ringa_lee

    ringa_lee2017-04-10 12:43:54

    我的理解:
    是查找的Function.prototype.method,Number实际上也是个function,所以会从原型查找到。
    Function也是从Object继承来的,所以改Object.prototype会影响到Function。
    严格来说function类型是object类型的一种,typeof之所以对function做了区分,是因为js中function是第一型的,可以当做参数传递等。
    至于5种原始类型,不包括对象类型的Function,是正常的

    可以参考周爱民的几篇文章:
    http://blog.csdn.net/aimingoo/article...
    http://blog.csdn.net/aimingoo/article...

    另外关于Function和Object的关系,补充两个
    http://www.planabc.net/2010/05/06/int...
    http://www.cnblogs.com/objectorl/arch...

    返事
    0
  • 大家讲道理

    大家讲道理2017-04-10 12:43:54

    推荐你看下一篇经典的介绍javascript的原型以及原型链的博文,很有深度又感觉通俗易懂.我原先对这个概念也很模糊,理解了,好像有没理解,看过该文以后,基本有了一个清晰的认识,通过几天的深入理解,可以说现在基本掌握了。

    这个关键的概念只要你懂了,基本其它的也就很容易懂了。好好阅读下吧,希望对你有所帮助,链接在下面:

    深入理解javacript之prototype

    返事
    0
  • PHP中文网

    PHP中文网2017-04-10 12:43:54

    为了说明这个问题,我给你列几个等式吧,其中A是构造函数,a是A的实例(即a = new A
    1. a.constructor = A 实例的构造函数
    2. a.[[proto]] = A.prototype 实例的原型等于其构造函数的prototype对象
    3. Object.prototype.[[proto]] = null 这是‘金字塔’的顶端的象征。

    再来给你理一下一些Js的基本准则:
    1. 一切构造函数A均有prototype对象
    2. 一切对象a均有原型[[proto]]
    3. 当访问(get)实例a上的某个熟悉key时,会首先检查该实例a上是否直接存在key属性,如果有,则返回值,否则检查a的原型是否具有key属性,如果有,则返回,无则继续检查a的原型的原型,以此类推,直到检查到某个原型的值为null为止(Object.prototype.[[proto]] = null)。该过程就是javascript的原型链。
    4. Js的内置构造函数Array,String,Boolean,Date,RegExp,Object,Function,Number等均是函数实例。
    5. 函数也是对象Object的实例,构造函数也不例外。
    6. 构造函数的prototype对象也有原型。

    基本知识普及完成了,然后回到你的code看看
    Number.method()调用的时候涉及到Number的method属性的访问(get),于是根据准则3加上准则4,访问到了
    Number.[[proto]].method 刚好等于 Function.prototype.method,如果不在Function.prototype上定义method属性,则根据准则3,它开始查找Number.[[proto]]的原型,即Function.prototype的原型,即Object.prototype。
    这就是你在Function.prototype和Object.prototype上定义method属性的时候,Number.method能生效的原因.
    再说说为什么Number.prototype上定义不生效的原因吧,其实由准则3就能看出来根本不会查找Number.prototype这个对象,如果换成

    javascriptNumber.prototype.method = function () {};
    var a = new Number();
    a.method();
    

    此时就会生效。

    最后说一下你的代码中method内this的使用造成了你的method属性只能使用在构造函数上,幸好你是使用在Number这个构造函数上的,如果你使用在一个非构造函数的实例上,就会有问题

    返事
    0
  • キャンセル返事