嘛,放假了总会有很多时间去复(tian)习(keng),刚好复习下魔性的js。。。怎么说呢,语言设计的时候嫌麻烦偷懒,意外的让前端聚聚们们玩的很欢呢orz…

工厂模式

function createObject(prop) {
    var obj = {};
    obj.prop = prop;
    obj.func = function () {
        console.log("I'm a function")
    };
    return obj;
}

构造函数

function Object(prop) {
    this.prop = prop;
    this.func = function () {
        console.log("I'm a function");
    }
}

var obj = new Object("test");

obj.func();

构造函数假如当作普通函数作用域绑在global上面注意

问题:

ECMAScript中的函数其实是对象,这样的话构造函数实例化的不同对象里面的函数都不同

原型模式

和构造函数模式搭配使用效果更佳

function getFunc() {
    var i = Math.floor(Math.random() * 100);
    return function () {
        console.log("My value:" + i);
    }
}


function Object() {
}

Object.prototype = {
    prop: "Test",
    func: getFunc()
};


var obj1 = new Object();
var obj2 = new Object();

obj1.func();
obj2.func();

动态原型模式

避免了function对象的重复定义

function Object(prop) {
    this.prop = prop;
    if (typeof this.func != 'function') {
        Object.prototype.func = function () {
            console.log("I'm a function...");
        }
    }
}

var o1 = new Object('test1');
var o2 = new Object('test2');

寄生构造函数模式

这尼玛其实和工厂模式一样啊

稳妥构造函数模式

稳妥对象:没有公共属性,其方法也不引用this

function Object(prop) {
    var obj = {};
    //func是props的唯一入口
    obj.func = function () {
        console.log(prop);
    };
    return obj;
}

原型链

js中的继承,缺点…其实也不是缺点,其属性是实例共享的(prototype是引用)

function SuperType() {
    this.prop = true;
}

SuperType.prototype.getSuperValue = function () {
    return this.prop;
};

function SubType() {
    this.subprop = false;
}


SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function () {
    return this.subprop;
};

分析:

SuperType:[protoType->SuperType.prototype]
SuperType.prototype:[constructor->SuperType(),getSuperValue->function]
SubType:[protoType->SubType.prototype]
SubType.prototype:[protoType->SuperType.prototype,prop->true,getSubValue->function]
instance:[prototype->SubType.prototype,subprop->false]
其实最根源是Object的prototype,顺带复习下

Object.prototype:
constructor
hasOwnProperty(检测实例中的属性)
isPrototypeOf(检测是否在原型链中)
propertyIsEnumerable(检测实例中的可枚举属性)
toLocalString(Date专用)
toString(优先度低)
valueOf(优先度高)

借用构造函数

用新的作用域代替另一个构造函数的作用域,缺点也很明显 => 方法重复定义了

function SuperType(prop) {
    this.prop = prop;
}

function SubType() {
    SuperType.call(this, "test");
    this.subprop = '233';
}

var instance = new SubType();

console.log(instance.prop);

组合继承

同时使用借用构造函数和原型链,既避免了重复定义方法,也包含私有属性

function SuperType(prop) {
    this.prop = prop;
    this.values = ['value0', 'value1'];
}

SuperType.prototype.func = function () {
    console.log(this.values);
};

function SubType(prop) {
    SuperType.call(this, prop);
    this.newprop = true;
}

SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;

var obj1 = new SubType('test');
obj1.values.push('value2');
obj1.func();

var obj2 = new SubType('test');
obj2.values.push('value3');
obj2.func();

原型式继承

以参数传入构造函数的原型,生成的实例原型指向其,没什么好说的呢…

function instance(proto) {
    function Func() {
    }

    Func.prototype = proto;

    return new Func();
}

var superObj = {
    values: ["name0", "name1"]
};

var child1 = instance(superObj);
var child2 = instance(superObj);

child1.values.push("name2");
child2.values.push("name3");

console.log(superObj.values);

寄生式继承

在一个传入构造函数的基础上加加加

function SuperType(prop) {
    this.prop = prop;
    this.values = ['value0', 'value1'];
}

function copyAndAdd(original) {
    var copy = new original();
    copy.newprop = true;
    return copy;
}

寄生组合式继承

精简了组合式继承

function inherit(subType, superType) {
    var Prototype = function () {
    };
    Prototype.prototype = superType.prototype;
    var proto = new Prototype();
    proto.constructor = subType;
    subType.prototype = proto;
}