乐趣区

读书笔记1javascript语言精粹继承

构造器调用模式

当一个函数对象被创建时,Function 构造器会运行类似这样的代码:

this.prototype = {constructor: this}

new 一个函数事会发生:

Function.method('new', function() {
    // 创建新对象,继承原型
    let that = Object.create(this.prototype);
    // 调用构造函数,绑定 this 到新对象
    let res = this.apply(that, arguments);
    return typeof res === 'object' && res || that;
}); 

伪类继承

let Mammal = function(name) {this.name = name;}
Mammal.prototype.get_name = function() {return this.name;}

// 构造一个实例
let myMammal = new Mammal('zhangsan');
// 利用伪类继承 Mammal
let Cat = function(name) {
    this.name = name;
    this.age = age;
}

Cat.prototype = new Mammal();
Cat.prototype.get_age = function() {return this.age;}

let myCat = new Cat('miao');

以上就是一个简单的伪类继承。使用构造器有个严重的危害,如果在调用构造器函数的时候忘记使用 new 前缀,this 不仅不会绑定到新对象,还会污染全局变量;

原型模式

原型模式中,我们采用对象来继承。

let myMammal = {
    name: 'aa',
    age: 22,
    get_name: function() {return this.name;}
}

let myCat = Object.create(myMammal);
Cat.get_age = function() {return this.age;}

这种继承方式,导致没有私有属性和私有函数

函数化模式

它的每一层都是在扩充 that

Function.prototype.method = function (name,func) {this.prototype[name] = func;
    return this; 
}
// 工厂 mammal 函数
var mammal = function (spec) {var that = {};

    that.get_name = function () {return spec.name;}
    that.says = function (spec) {return spec.saying || '';} 

    return that;
}

// 工厂 cat 函数 (基于 mammal 的函数)
var cat = function (spec) {
    spec.saying = spec.saying || 'meow';
    // 直接调用 mammal 函数
    var that = mammal(spec);
    that.purr = function (n) {
        var i, s = '';
        for (i = 0; i < n; i += 1) {if(s) {s += '-';}
            s += 'r';
        }
    }
    that.get_name = function () {return that.says() + '' + spec.name +' ' + that.says();}
    return that;
}

// 创建 myCat 对象
var myCat = cat({name: 'Henrietta'});

Object.method('superior',function (name) {
    var that = this,
        method = that[name];
    return function () {return method.apply(that, arguments)
    }
})

// 工厂 coolcat 函数 (基于 cat 函数)
var coolcat = function (spec) {var that = cat(spec),
        super_get_name = that.superior('get_name');
    that.get_name = function (n) {return 'like' + super_get_name() + 'baby';
    }
    return that;
}

var myCoolCat = coolcat({name : 'Bix'});

var name = myCoolCat.get_name();

部件

没看懂。。

let eventuality = function(that) {let registry = {};
    that.fire = function(event) {
        let array, 
            func,
            handler,
            i,
            type = typeof event === 'string' ? event : event.type;
        if (registry.hasOwnProperty(type)) {array = registry[type];
            for(i = 0; i < array.length; i++) {handler = array[i];
                func = handler.method;
                if (typeof func === 'string') {func = this[func];
                }
                func.apply(this, handler.parameters || [events]);
            }
        }
        return this;
            
    }
    that.on = function(type, method, parameters) {
        let handler= {
            method,
            parameters
        };
        if (registry.hasOwnProperty(type)) {registry[type].push(handler);
        } else {registry[type] = [handler];
        }
        return this;
    }
    return that;
}
退出移动版