#声明、例化
构造函数模式用于定义实例的属性,而原型模式(原型是一个指针)用于定义方法和共享的属性:
尽量将方法定义为原型方法,原型方法避免了每次调用构造函数时对属性或方法的构造,节省空间,创建对象快.
<script>
function Person(name) {
//使用原型方法扩充的方法可以在类内部使用
//使用原型方法扩充的属性可以在类内部使用
//私有属性,只能在对象构造函数内部使用
var privateName = "privateName";
//公有属性,在对象实例化后调用
this.name = name;
this.lessons = ['Math', 'Physics'];
//对象方法
this.fun = function(){
}
}
}
//如果原型方法当作静态方法直接调用时,构造函数属性无法被调用
//原型属性,当作是类内部的属性使用【this.原型属性】,也可以当成公有静态属性使用【对象.prototype.原型属性】
Person.prototype = {
//原型属性1
constructor: Person,
//原型方法1
getName: function () {
return this.name;
}
}
//原型属性2
Person.prototype.sex = "男";
//原型方法2
Person.prototype.fun = function(){
}
//公有静态属性(类属性)
//公有静态属性不能使用 【this.属性】,只能使用 【对象.属性】 调用
Person.age = 20;
//公有静态方法(类方法)
Person.fun = function(){
}
var person1 = new Person('Jack');
person1.lessons.push('Biology');
var person2 = new Person('Lily');
alert(person1.lessons);//Math,Physics,Biology
alert(person2.lessons);//Math,Physics
alert(person1.name === person2.name);//false,//不共享构造函数定义属性
alert(person1.getName === person2.getName);//true,//共享原型中定义方法
</script>
除了对象方法、原型方法必须实例化对象,其余都可以做静态方法(属性)调用,即不需要new
,直接用Class.fun()或Class.property
调用。
#继承
//先把固定的方法写上
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
//A继承B,A和B是构造函数
extend(A,B);
#闭包(匿名函数是闭包的一种)
在函数里A的再定义一个函数B并访问A的局部变量,在B里写对局部变量的操作并把B作为返回值,把B取出并执行,相当于访问A的局部变量(或者在A内定义一个不用var修饰的匿名函数C,在C里操作A的局部变量,再在外部调用C)。
把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value)
function A(){
var n=999;
C=function(){n+=1}//匿名函数
function B(){//操作局部变量并作为返回值
alert(n);
}
return B;
}
var result=A();//获取返回值
result(); // 999//通过内部函数返回值实现闭包,相当于在函数A外操作A的局部变量n
C();//通过匿名函数实现闭包,相当于在函数A外操作A的局部变量n,
result(); // 1000 //证明n值一直在内存中没被销毁(普通局部变量在函数调用结束后会被销毁),B依赖于A,B被赋给全局变量,A和B也存在与内存中。
#反射(避免switch,动态执行方法或new对象)
- eval反射
eval("this."+方法名字符串+"()");//括号里可以写参数
//括号里可以写参数
var funcName = 'funStr';
var obj = new window[funcName]();
//或
var funcName = 'funStr';
window[funcName]();//相当于 funStr();