【问题标题】:mootools Type functionmootools 类型函数
【发布时间】:2012-06-14 18:36:30
【问题描述】:

所以我正在尝试通过学习 Mootools 内部的工作原理来学习 javascript。我正在看这些行:

var Type = this.Type = function(name, object){
    if (name){
        var lower = name.toLowerCase();
        var typeCheck = function(item){
            return (typeOf(item) == lower);
        };

        Type['is' + name] = typeCheck;
        if (object != null){
            object.prototype.$family = (function(){
                return lower;
            }).hide();

        }
    }

    if (object == null) return null;

    object.extend(this);
    object.$constructor = Type;
    object.prototype.$constructor = object;

    return object;
};

//some more code

new Type('Type',Type);

这里发生了什么?

在底部的构造函数语句中被分配的对象是什么,全局窗口对象?

当 Type 函数似乎只更新传入的对象而不是创建一个新对象时,为什么它被作为带有 new 语句的构造函数调用?

具体来说,object.extend(this); 中的“this”是什么? ?是全局窗口对象吗,如果是的话,是否将该对象的所有键值对添加到 Type 对象中?

【问题讨论】:

    标签: javascript object constructor mootools


    【解决方案1】:

    哎呀,最近的问题似乎更多地集中在 mootools 内部。

    我会尽我所知回答,因为我不是核心开发者。

    MooTools 中的Type 与 Class(实际上是 Class constructor itself is a Type)非常相似,但它更关注数据/值和值的类型。它还旨在扩展 ECMA 规范定义的原生类型并使其更加灵活。

    我想一般来说谈论数据类型是没有意义的(StringNumberArrayObject 等)。为什么需要扩展它们?好吧,对于初学者来说,Duct Typing 在 js 中有点古怪。 typeof {}; // objecttypeof []; // objecttypeof new Date(); // object 等 - 不是最有帮助的,即使因为所有类型都继承自 object 并且将它们组合在一起是合乎逻辑的,它也无助于您编写代码。

    所以,在 js 对象的上下文中,它们是由构造函数对象创建的......

    Type 所做的不是替换构造函数,而是通过向其添加新方法或属性来更改现有构造函数。

    例如。 new Type('Array', Array);

    这会将原生 Array 构造函数转换为某种类型的对象。您无需保存结果或任何内容 - 这是一种一次性操作,可以修改原始文件并使其保持打开状态以供操作。

    typeOf(Array); // type

    那么,有什么不同呢?好吧,对于初学者来说,typeOf([]) 现在能够真正告诉我们它到底是什么 - array。这里真正发生的是:object.extend(Type);,神奇的一点。它会将 Type 对象上定义的所有属性复制到目标对象 - 您可以在此处查看它们:

    https://github.com/mootools/mootools-core/blob/master/Source/Core/Core.js#L211-232

    因此,您新创建的 Type 立即获得了所有重要的 implementextend 方法。

    更高级,让我们创建一个基于原生 Array 构造函数的新类型:

    var foo = new Type('foo', Array),
        a = new foo();
    // it's a real boy!
    a.push('hi');
    // ['hi'], foo, object
    console.log(a, typeOf(a), typeof a);
    

    但是,如果我们想要自定义类型怎么办?一个神奇而特别的?没问题,因为参数 2 实际上可以是一个(匿名)函数。

    var Awesome = new Type('awesome', function(name, surname) {
        // console.log('I R teh construct0r!'); 
        this.name = name;
        this.surname = surname;
    });
    
    // extend it a little.
    Awesome.implement({
        getName: function() {
            return this.name;
        },
        getSurname: function() {
            return this.surname;
        }
    });
    
    var Dimitar = new Awesome('dimitar', 'christoff');
    console.log(typeOf(Dimitar)); // awesome
    console.log(Dimitar.getName()); // dimitar
    

    在另一个示例中,查看 DOMEvent。它采用上述方法,使其成为更快更精简的 Object 类型。 https://github.com/mootools/mootools-core/blob/master/Source/Types/DOMEvent.js#L21

    那为什么不是一门课呢?因为,课程更昂贵,并且事件一直在发生。

    我希望这对您有所帮助。要获得更详细的解释,请在邮件列表中询问并希望得到最好的结果,也许核心开发人员会有时间,因为这不是您的标准“如何让手风琴工作”类型的问题......

    【讨论】:

    • 请参阅此,了解使用 Type 向 Types 添加断言的富有想象力的方式。 github.com/GCheung55/Is.js/blob/…
    • 感谢您的出色回答,我想了解核心模块,以便更好地了解 JS 并了解 MooTools 库的其余部分。你在这方面帮助了我很多。我能问一下为什么 Type('Type',Type);如果只是更新 Type 函数,需要用 new 调用吗?没有new就不能调用吗?
    • 哦...这不是一个快速的主题。基本上。对象构造函数在实例化时需要new,这会将函数内的范围设置为新的宿主对象本身。否则,this 仍然是全局对象(例如,窗口),因此对this.$events 等属性的引用将寻找window.$events。在此处阅读有关范围/构造函数的更多信息 - bonsaiden.github.com/JavaScript-Garden/#function.this。试试看 - var foo = function() { this.bar = 'hello'; }; var ret = new foo(); console.log(ret, window.bar); foo(); console.log(window.bar);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多