Javascript 在MooTools中,什么';.implement和.prototype之间的区别是什么

Javascript 在MooTools中,什么';.implement和.prototype之间的区别是什么,javascript,mootools,Javascript,Mootools,实现change prototype,那么为什么不直接使用“some class”对其进行目录更改呢?prototype…,它看起来非常无用或唠叨您可以查看MooTools源代码或检查控制台中的MooTools对象,以查看调用implement()时它在后台做什么 在MooTools 1.4.5中,它是这样做的: function (key, value){ if ($type(key) == 'object'){ for (var p in key) this.imp

实现change prototype,那么为什么不直接使用“some class”对其进行目录更改呢?prototype…,它看起来非常无用或唠叨

您可以查看MooTools源代码或检查控制台中的MooTools对象,以查看调用
implement()
时它在后台做什么

在MooTools 1.4.5中,它是这样做的:

function (key, value){

    if ($type(key) == 'object'){
        for (var p in key) this.implement(p, key[p]);
        return this;
    }

    var mutator = Class.Mutators[key];

    if (mutator){
        value = mutator.call(this, value);
        if (value == null) return this;
    }

    var proto = this.prototype;

    switch ($type(value)){

        case 'function':
            if (value._hidden) return this;
            proto[key] = Class.wrap(this, key, value);
        break;

        case 'object':
            var previous = proto[key];
            if ($type(previous) == 'object') $mixin(previous, value);
            else proto[key] = $unlink(value);
        break;

        case 'array':
            proto[key] = $unlink(value);
        break;

        default: proto[key] = value;

    }

    return this;

}
正如你所看到的,这里肯定有一些额外的逻辑。例如,您似乎可以为
key
value
传递具有相应属性名称的对象,以使其在一次调用中实现向对象原型添加多个内容


我会使用
implement()
,避免直接向原型链添加内容,除非您非常确定自己知道自己在做什么。毫无疑问,这些额外的东西是有原因的。

有两个方面需要实现。在类上下文和对象(类型/本机)上

共同利益 它们之间的共同点是,它们是API。因为它是API,所以MooTools可以添加一些方法,确保您不会(意外地)覆盖在各种本机类型上受保护的原型方法。请参阅此位,它强制保护许多本机方法:

此外,implement是重载的——这意味着您可以传递一个同时实现多个方法的对象,而不是中断并为每个原型调用换行

类中的函数方法被包装

这些装饰器可用:

Function.implement({

    hide: function(){
        this.$hidden = true;
        return this;
    },

    protect: function(){
        this.$protected = true;
        return this;
    }

});
这意味着你能做到

Obj.implement({
   foo: foo.hide(),
   bar: bar.protect()
});
这允许您通过
.hide()
使用非包装方法来添加未包装的属性:

Number.prototype.$family = function(){
    return isFinite(this) ? 'number' : 'null';
}.hide();
类使用了
.protect()
,请参见下文

这并不意味着你不能做
Number.prototype.$family=somethingElse
-你可以

课堂细节 在类构造函数上使用
implement
时,请注意引用
$hidden
并调用
wrap()

这意味着当你传递一个函数时,它将被自动包装-包装使你能够通过
.protect()
装饰器拥有私有方法,或者通过
.hide()
decorator拥有特殊方法

它还支持类变异体-您应该检查这一点,但它能够定义可以修改构造函数的特殊键,而不仅仅是添加到原型中

同样,您可以轻松地执行以下操作:

ClassConstructor.prototype.foo = someFn;
这就行了

// but:
ClassConstructor.prototype.foo = someFn.protect();

// however...
instanceOfClassconstructor.foo(); // works also.
见此:

// generic method.
var foo = function() {
    console.log('hi');
};

var ClassConstructor = new Class({});

// implement the foo method as private.
ClassConstructor.implement({
    foo: foo.protect()
});

var instance = new ClassConstructor();

// try to call it, will throw.
try {
    instance.foo();
}
catch(e) {
    console.warn(e);
}

// do it directly on the prototype
ClassConstructor.prototype.foo = foo.protect();

var instance2 = new ClassConstructor();
instance2.foo(); // works.

不知道在哪里可以找到这些文件这里有一个网站,谷歌,它将改变世界。如果你太懒了,以至于你懒得去谷歌找文档,我们为什么要费心帮你?
// generic method.
var foo = function() {
    console.log('hi');
};

var ClassConstructor = new Class({});

// implement the foo method as private.
ClassConstructor.implement({
    foo: foo.protect()
});

var instance = new ClassConstructor();

// try to call it, will throw.
try {
    instance.foo();
}
catch(e) {
    console.warn(e);
}

// do it directly on the prototype
ClassConstructor.prototype.foo = foo.protect();

var instance2 = new ClassConstructor();
instance2.foo(); // works.