嘛,放假了总会有很多时间去复(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;
}