js的面向对象
//1. 封装
//工厂方式
function createPerson(){
var person = {};
person.name = "Lubin";
person.age = 23;
person.work = function(){
alert("writing code");
}
return person;
}
var per1 = createPerson();
var per2 = createPerson();
alert(per1.name);
per2.name = "shen";
alert(per1.name);
alert(per2.name);
//构造函数
function fPerson(){
this.name = "Luibn";
this.age = 23;
this.work = function(){
alert("writing code");
}
}
var objp1 = new fPerson();
var objp2 = new fPerson();
alert(objp1.age);
objp2.age = 22;
alert(objp1.age);
//原型方式
function pPerson(){}
pPerson.prototype.name = "Lubin";
pPerson.prototype.age = 23;
pPerson.prototype.work = function(){
alert("writing code");
}
//pPerson.prototype = { name:"json" }
//使用json字符串会覆盖掉上面的属性与方法
var objpp1 = new pPerson();
var objpp2 = new pPerson();
objpp1.name = "shen";
alert(objpp1.name);
alert(objpp2.age);
/*
构造函数方式可以传参数,原型方式不能传参数,
因此两者可以混合使用
*/
//公有与私有
function cPerson(name){
var pName = name; //作用域在函数体内,其他不能访问,私有的
this.getName = function(){ //通过this关键字实现了变量的传递,公有的
return pName;
}
this.age = 23;
}
//全局变量
(function(){
height = "i am height!";// 没有用var 就隐式声明了一个全局变量
var h = "i am h!";
})();
alert(height);
alert(h);
//静态方法,静态属性
function sPerson(){
this.name = "L"; //实例属性
this.work = function(){ //实例方法
alert("writing code");
}
}
sPerson.age = 23; //类属性(静态属性)
sPerson.sayAge = function(){ //类方法(静态方法)
alert(23);
}
var objP1 = new sPerson();
alert(objP1.name);
alert(sPerson.sayAge);
//封装的一些额外话题
//早绑定、晚绑定与极晚绑定
/*
早绑定是在实例化对象之前,进行了方法和属性的定义。
这样编译器或解释器能提前转化为机器码,就能被良好的IDE
智能感知。是C# java等强类型语言的特性。
Request objReq 在运行前就知道objReq是Request类型
*/
/*
晚绑定是指编译器或解释器在运行之前不知道是对象的类型。
因此,无须对象的类型,只要检查它是否支持属性与方法,
若不支持则为undefined类型,可以进行大量的对象操作,
不会有任何惩罚。
var 关键字可以是晚绑定的一种表现
var obj 编译器或解释器在运行之前不知道它是什么类型的
obj为undefined。
var obj = new String(); 在运行之前还是不知道它是什么类型的
在运行之后才知道它是String()类型的。
JS中所有的对象都是晚绑定的,它是弱类型语言;
*/
/*
极晚绑定是指在实例化对象之后还能定义对象的属性和方法
var str = new String();
String.prototype.name = "i am string"; //方式一
str.fnName = "i am fnName"; //方式二
alert(str.name);
alert(str.fnName);
*/
//深拷贝与浅拷贝
function copy(){
this.name = "copy";
this.arrDeep = ["deep"];
}
copy.prototype.arrShallow = ["shallow"];
var objCopy1 = new copy();
var objCopy2 = new copy();
alert(objCopy1.arrDeep + "------" + objCopy1.arrShallow);
objCopy2.arrDeep.unshift("newArr");
objCopy2.arrShallow.unshift("newArr");
//alert(objCopy2.arrDeep + "------" + objCopy2.arrShallow);
alert(objCopy1.arrDeep + "------" + objCopy1.arrShallow);
/*
通过this实现了深拷贝,新的对象开辟了内存存放了原始值与引用值
而对原型拷贝是浅拷贝,栈中的原始值还是拷贝了一份,而引用值只拷贝
栈中引用地址,因此对objCopy1的操作会影响到objCopy2。
*/
//2.继承
//对象冒充
function Person(){
this.name = "Lubin";
this.walk = function(){
alert("i am walk!");
}
}
function Student(){
this.newMethod = Person;
this.newMethod();
delete this.newMethod;
//上面三行代码实现了对象冒充
/*
Person中的this指的是window,
赋值给newMethod,执行之后指的就是
newMethod的this.new之后this就是objStu
objStu也就拥有了Person的方法。
之后须delete掉newMethod,要不然可操作
newMethod来改变newMethod中的Perosn,使他和原来的
Person不一样,就会破坏继承。
对象冒充能实现多继承。
*/
this.school = "shuizhuan";
this.study = function(){
alert("i am study!");
}
}
var objStu = new Student();
alert(objStu.name);
/*
用 call 与 apply 来实现继承其实就是对象冒充原理的运用
两则不同就是参数传入在Call一个个来,在apply中传个数组
*/
function car(speed,color){
this.runSpeed = speed;
this.cColor = color;
this.name = "car";
}
function bus(){
car.call(this,60,"blue");
}
function racingCar(){
car.apply(this,[120,"red"]);
}
var objBus = new bus();
var objRacingCar = new racingCar();
alert(objBus.runSpeed);
alert(objRacingCar.cColor);
//原型继承
function boy(){
this.age = 12;
//this.name = ["jim","tom"];
}
boy.prototype.sex = "male";
boy.prototype.name = ["jim","tom"];
function man(){
//this.age = 22;
}
man.prototype = new boy();
var objMan = new man();
objMan.name.unshift("Joee","Jion");
alert(new man().age);
var objBoy = new boy();
alert(objBoy.name);
/*
原型继承方式拷贝一份父类赋给子类的原型,它只能实现单一继承,
原型继承是由原型拷贝实现的,父类中的原型是浅拷贝,性能比较好
对象冒充继承是通过this实现的,因此他是深拷贝,性能比较差一点
但是能实现多继承。
*/
//继承中的一些额外话题
//this 关键字
/*
in JavaScript this always refers to the 'owner' of the funcion
we're executing,or rather,to the object that a function is a method of
这是对this官方的解释。就是this指代在执行环境中的拥有者。
举个例子简单的解释下
*/
function fun1(){
alert(this.id);
}
fun1();
//fun1的作用域链是window,在执行环境创建的活动对象中搜索不到id,因此输出undefined
dv1.onclick = fun1; //dv1是个dom对象,这时fun1的执行环境就是在dv1的onclick的执行环境
//在执行环境创建的活动对象中搜索到了id,因此输出dv1;
//new 关键字
/*
其实也是通过this实现,跟对象冒充的点类似。
new的运作过程:首先是创建以个Object,然后把构造函数中的this指向Object,
最后返回Object.
*/
function testNew(){
this.name = "new Key Wold";
}
//testNew.prototype.attr = "i am pAttr";
var obj = {};
testNew.call(obj);
alert(obj.name);
//工厂方式
function createPerson(){
var person = {};
person.name = "Lubin";
person.age = 23;
person.work = function(){
alert("writing code");
}
return person;
}
var per1 = createPerson();
var per2 = createPerson();
alert(per1.name);
per2.name = "shen";
alert(per1.name);
alert(per2.name);
//构造函数
function fPerson(){
this.name = "Luibn";
this.age = 23;
this.work = function(){
alert("writing code");
}
}
var objp1 = new fPerson();
var objp2 = new fPerson();
alert(objp1.age);
objp2.age = 22;
alert(objp1.age);
//原型方式
function pPerson(){}
pPerson.prototype.name = "Lubin";
pPerson.prototype.age = 23;
pPerson.prototype.work = function(){
alert("writing code");
}
//pPerson.prototype = { name:"json" }
//使用json字符串会覆盖掉上面的属性与方法
var objpp1 = new pPerson();
var objpp2 = new pPerson();
objpp1.name = "shen";
alert(objpp1.name);
alert(objpp2.age);
/*
构造函数方式可以传参数,原型方式不能传参数,
因此两者可以混合使用
*/
//公有与私有
function cPerson(name){
var pName = name; //作用域在函数体内,其他不能访问,私有的
this.getName = function(){ //通过this关键字实现了变量的传递,公有的
return pName;
}
this.age = 23;
}
//全局变量
(function(){
height = "i am height!";// 没有用var 就隐式声明了一个全局变量
var h = "i am h!";
})();
alert(height);
alert(h);
//静态方法,静态属性
function sPerson(){
this.name = "L"; //实例属性
this.work = function(){ //实例方法
alert("writing code");
}
}
sPerson.age = 23; //类属性(静态属性)
sPerson.sayAge = function(){ //类方法(静态方法)
alert(23);
}
var objP1 = new sPerson();
alert(objP1.name);
alert(sPerson.sayAge);
//封装的一些额外话题
//早绑定、晚绑定与极晚绑定
/*
早绑定是在实例化对象之前,进行了方法和属性的定义。
这样编译器或解释器能提前转化为机器码,就能被良好的IDE
智能感知。是C# java等强类型语言的特性。
Request objReq 在运行前就知道objReq是Request类型
*/
/*
晚绑定是指编译器或解释器在运行之前不知道是对象的类型。
因此,无须对象的类型,只要检查它是否支持属性与方法,
若不支持则为undefined类型,可以进行大量的对象操作,
不会有任何惩罚。
var 关键字可以是晚绑定的一种表现
var obj 编译器或解释器在运行之前不知道它是什么类型的
obj为undefined。
var obj = new String(); 在运行之前还是不知道它是什么类型的
在运行之后才知道它是String()类型的。
JS中所有的对象都是晚绑定的,它是弱类型语言;
*/
/*
极晚绑定是指在实例化对象之后还能定义对象的属性和方法
var str = new String();
String.prototype.name = "i am string"; //方式一
str.fnName = "i am fnName"; //方式二
alert(str.name);
alert(str.fnName);
*/
//深拷贝与浅拷贝
function copy(){
this.name = "copy";
this.arrDeep = ["deep"];
}
copy.prototype.arrShallow = ["shallow"];
var objCopy1 = new copy();
var objCopy2 = new copy();
alert(objCopy1.arrDeep + "------" + objCopy1.arrShallow);
objCopy2.arrDeep.unshift("newArr");
objCopy2.arrShallow.unshift("newArr");
//alert(objCopy2.arrDeep + "------" + objCopy2.arrShallow);
alert(objCopy1.arrDeep + "------" + objCopy1.arrShallow);
/*
通过this实现了深拷贝,新的对象开辟了内存存放了原始值与引用值
而对原型拷贝是浅拷贝,栈中的原始值还是拷贝了一份,而引用值只拷贝
栈中引用地址,因此对objCopy1的操作会影响到objCopy2。
*/
//2.继承
//对象冒充
function Person(){
this.name = "Lubin";
this.walk = function(){
alert("i am walk!");
}
}
function Student(){
this.newMethod = Person;
this.newMethod();
delete this.newMethod;
//上面三行代码实现了对象冒充
/*
Person中的this指的是window,
赋值给newMethod,执行之后指的就是
newMethod的this.new之后this就是objStu
objStu也就拥有了Person的方法。
之后须delete掉newMethod,要不然可操作
newMethod来改变newMethod中的Perosn,使他和原来的
Person不一样,就会破坏继承。
对象冒充能实现多继承。
*/
this.school = "shuizhuan";
this.study = function(){
alert("i am study!");
}
}
var objStu = new Student();
alert(objStu.name);
/*
用 call 与 apply 来实现继承其实就是对象冒充原理的运用
两则不同就是参数传入在Call一个个来,在apply中传个数组
*/
function car(speed,color){
this.runSpeed = speed;
this.cColor = color;
this.name = "car";
}
function bus(){
car.call(this,60,"blue");
}
function racingCar(){
car.apply(this,[120,"red"]);
}
var objBus = new bus();
var objRacingCar = new racingCar();
alert(objBus.runSpeed);
alert(objRacingCar.cColor);
//原型继承
function boy(){
this.age = 12;
//this.name = ["jim","tom"];
}
boy.prototype.sex = "male";
boy.prototype.name = ["jim","tom"];
function man(){
//this.age = 22;
}
man.prototype = new boy();
var objMan = new man();
objMan.name.unshift("Joee","Jion");
alert(new man().age);
var objBoy = new boy();
alert(objBoy.name);
/*
原型继承方式拷贝一份父类赋给子类的原型,它只能实现单一继承,
原型继承是由原型拷贝实现的,父类中的原型是浅拷贝,性能比较好
对象冒充继承是通过this实现的,因此他是深拷贝,性能比较差一点
但是能实现多继承。
*/
//继承中的一些额外话题
//this 关键字
/*
in JavaScript this always refers to the 'owner' of the funcion
we're executing,or rather,to the object that a function is a method of
这是对this官方的解释。就是this指代在执行环境中的拥有者。
举个例子简单的解释下
*/
function fun1(){
alert(this.id);
}
fun1();
//fun1的作用域链是window,在执行环境创建的活动对象中搜索不到id,因此输出undefined
dv1.onclick = fun1; //dv1是个dom对象,这时fun1的执行环境就是在dv1的onclick的执行环境
//在执行环境创建的活动对象中搜索到了id,因此输出dv1;
//new 关键字
/*
其实也是通过this实现,跟对象冒充的点类似。
new的运作过程:首先是创建以个Object,然后把构造函数中的this指向Object,
最后返回Object.
*/
function testNew(){
this.name = "new Key Wold";
}
//testNew.prototype.attr = "i am pAttr";
var obj = {};
testNew.call(obj);
alert(obj.name);
//3.多态
//方法重载
function tFun(){
if(arguments.length == 1){
alert("i am function 1");
//....code....
}
if(arguments.length == 2){
if(typeof arguments[0] === "number" && typeof arguments[1] === "number"){
alert("i am function 2");
//....code....
}
if(typeof arguments[0] === "number" && typeof arguments[1] === "string"){
alert("i am function 3");
//....code....
}
}
}
tFun(12);
tFun(12,12);
tFun(12,"12");
//通过判断参数个数与类型实现重载

浙公网安备 33010602011771号