对照scala,用javascript完成 特质(trait) 的部份特征

特质(trait)是scala的一个重要的特征,重要的运用体式格局有两个方面:1.拓宽瘦接口为胖接口。2.定义可堆叠的转变。
trait相对于多重继续而言最天真的一方面就是super所指定的对象只要到被混入以后才肯定。
由于特质内里既能够有字段要领,还能够既只写要领的范例,也能够写上要领的完成(不像JAVA的接口那样),而且能够混入到类中,类也能够运用恣意多的特质。相称的天真。

就混入到类中,和胖瘦接口而言,对javascript来讲几乎就是生成的,何足道哉(但javascript的问题是,以弱范例换来的天真,有时候总觉得天真的都不像话,迥殊不容易明白其他jser的代码)。

就[可堆叠的转变]而言:以下scala代码:

import scala.collection.mutable.ArrayBuffer

abstract class IntQueue {
    def get(): Int
    def put(x: Int)
}

class BasicIntQueue extends IntQueue {
    private val buf = new ArrayBuffer[Int]
    def get() = buf.remove(0)
    def put(x: Int) { buf += x }
}

// val queue = new BasicIntQueue
// queue.put(10)
// queue.put(20)
// queue.get()
// queue.get()

trait Doubling extends IntQueue {
    abstract override def put(x: Int) { super.put(2 * x) }
}

class MyQueue extends BasicIntQueue with Doubling
// val queue = new MyQueue
// queue.put(10)
// println(queue.get())
val queue = new BasicIntQueue with Doubling
// queue.put(10)
// println(queue.get())

trait Incrementing extends IntQueue {
    abstract override def put(x: Int) { super.put(x + 1) }
}

trait Filtering extends IntQueue {
    abstract override def put(x: Int) {
        if(x >= 0) super.put(x)
    }
}

val queue1 = new BasicIntQueue with Doubling with Incrementing with Filtering
queue1.put(-1)//先实行Filtering,-1 被过滤掉了
queue1.put(0) // 实行过滤,然后 +1,然后 *2
queue1.put(1)
println(queue1.get())
println(queue1.get())

javascript的完成:
代码链接:https://github.com/peichao01/test2/tree/master/javascript/trait

function trait (konstructor, traits) {
    traits = [].slice.call(arguments, 1);
    function _trait(reciever, trait_, parentName){
        for(var methodName in trait_){
            if(reciever.hasOwnProperty(methodName)){
                var method = trait_[methodName];
                if((typeof method == 'function') && 
                    (typeof reciever[methodName] == 'function') &&
                    (method.toString().indexOf(parentName) > -1)) {
                    var baseMethod = reciever[methodName];
                    reciever[methodName] = function(){
                        var baseSaved = this[parentName];
                        this[parentName] = baseMethod;
                        var result = method.apply(this, arguments);
                        this[parentName] = baseSaved;
                        return result;
                    };
                }
                else {
                    reciever[methodName] = method;
                }
            }
        }
    }
    function mixinTrait (reciever) {
        for(var i = 0, len = traits.length; i < len; i++){  
            _trait(reciever, traits[i], 'super');
        }
    }
    function Constructor(){
        konstructor.apply(this, arguments);
        mixinTrait(this);
    }
    for(var key in konstructor.prototype){
        if(konstructor.prototype.hasOwnProperty(key)) Constructor.prototype[key] = konstructor.prototype[key];
    }
    mixinTrait(Constructor.prototype);
    return Constructor;
}

function BasicIntQueue(name){
    this.name = name;
    this._buf = [];
}
BasicIntQueue.prototype.get = function(){
    return this._buf.shift();
};
BasicIntQueue.prototype.put = function(x){
    this._buf.push(x);
};
function BasicIntQueue2(name){
    this.name = name;
    this._buf = [];

    this.get = function(){
        return this._buf.shift();
    };

    this.put = function(x){
        this._buf.push(x);
    };
}

var trait_Doubling = {
    put: function(x){
        this.super(2 * x);
    }
};
var trait_Incrementing = {
    put: function(x){
        this.super(x + 1);
    }
};
var trait_Filtering = {
    put: function(x){
        if(x >= 0) this.super(x);
    }
};

var Klass = trait(BasicIntQueue2, trait_Doubling, trait_Incrementing, trait_Filtering);
var queue = new Klass('Klass');
var queue1 = new BasicIntQueue('BasicIntQueue');

queue1.put(-1);

queue.put(-1);
queue.put(0);
queue.put(1);

console.log(queue.get()); // 2
console.log(queue.get()); // 4
console.log(queue.get()); // undefined
    原文作者:超2真神
    原文地址: https://segmentfault.com/a/1190000000479616
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞