面向对象的链式调用
1、 对象的链式调用
function Chain(){
this.n=0;//属性不一定一开始的时候全部都要初始化
this.fn1=function(_obj){//this指向 new Chain()实例化的对象
alert(this.n++);//注意:alert(this.n++)与this.fn1中的this 不一定指向的对象是一样的
return this;
}
this.fn2=function(){//同上
alert(this.n++);//注意:alert(this.n++)与this.fn1中的this 不一定指向的对象是一样的
return this;
}
}
var _chain1 = new Chain();
var _chain2 = new Chain();
_chain1.fn1().fn2();//依次弹出 0 , 1
_chain2.fn2().fn1();//依次弹出0 , 1
_chain1.fn1();//弹出 0
_chain2.fn2().fn1().fn2();//依次弹出 2 , 3 , 4(注意:由于前面的_chain2.fn2().fn1())
2、此代码能解决链式调用,但不能解决顺序执行
function Asynchronous(){
var _self=this;
//由于ajax的回调函数(callBack),this的指向指向window对象下,要想this指向new Asychronous()实例化对象,需要用_self=this,指向实例化对象
this.visitJson1=function(){
ajaxRequest("post","json1.json",true,null,function(data){
alert(data);
});
}
this.visitJson2=function(){
ajaxRequest("post","json2.json",true,null,function(data){
alert(data);
});
}
this.visitJson3=function(){
ajaxRequest("post","json3.json",true,null,function(data){
alert(data);
});
}
}
var _async=new Asynchronous();
_async.visitJson1().visitJson2().visitJson3();//弹出的结果也不一定按照json1,json2,json3输出,由于ajax异步,不能同步输出(即顺序输出)
//正确的如下 (封装的ECMAScript 6中的promise函数)
function Asynchronous(fn){
this.list = [fn];//把promise当中所有的then内回调函数添加到数组中;之所以用数组,因为ajax是一个不确定什么时候执行完的机制,是异步的,
//要想要每个函数同步输出(顺序输出),需要把函数它们放进一个数组里面,依次执行
this.state = 0;//默认为回调函数未完执行成状态
this.n = 0;//作用:标记应该执行第几个回调函数
/**
* then作用:只是把回调函数存到数组当中,然后等待被调用。
*/
this.then = function(fx){
this.list.push(fx);
return this;
}
/**
* 等待被resolve方法按顺序调用,调用后执行数组中的特定的方法
*/
this.exec = function(n){
if(this.state == 1){
this.state == 0;//由于以后有出错 的属性 ,故需要state状态
this.fm = this.list[n];//注意:只将function赋值给this.fm,由于this.list[n]数组也是一个对象,this指向数组的某一项,达不到this指向实例化对象
this.fm();
}
}
/**
* 由回调函数来调用,实例化对象时也自动调用一次;
*/
this.resolve = function(){//表示执行该回调函数执行完成
this.state = 1;
if(this.n < this.list.length){
this.exec(this.n++);
}
}
this.resolve();
}
new Asynchronous(function(){
var _self = this;
ajaxRequest("post","json/json0.json",true,null,function(data){
alert(data);
_self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
});
}).then(function(){
var _self = this;
ajaxRequest("post","json/json1.json",true,null,function(data){
alert(data);
_self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
});
}).then(function(){
var _self = this;
ajaxRequest("post","json/json2.json",true,null,function(data){
alert(data);
_self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
});
}).then(function(){
var _self = this;
ajaxRequest("post","json/json3.json",true,null,function(data){
alert(data);
_self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
});
});
3、面向对象的继承
function Sign(){
this.account="";
this.password="";
this.sign=function(){
if(this.account=="abcde" && this.password=="123456"){
alert("登录成功");
}else{
alert("登录失败");
}
}
}
function Register(){
this.abc=0;
this.register=function(){
this.account="abcde";
this.password="123456";
}
}
function Exit(){
this.exit=function() {
this.account = null;
this.password = null;
}
}
Register.prototype=new Exit();//Register对象拥有Exit对象的实例属性和方法以及原型属性和方法
Sign.prototype=new Register();//Sign对象拥有Register对象的实例属性和方法以及原型属性和方法
var _user=new Sign();
_user.register();
_user.sign();//输出登录成功
_user.exit();
_user.sign();//输出登录失败
function main(){
alert(_user.hasOwnProperty("abc"));//输出false 对象.hasOwnProperty("属性名"); (boolean属性,检测"abc"是不是_user这个对象的实例属性
alert(Register.prototype.isPrototypeOf(_user));//输出true 对象属性.isPrototypeOf(对象); (boolean属性,检测“Register.prototypeOf”是不是"_user"这个对象的原型属性)
if("abc" in _user){//无论“abc”是_user这个对象的实例属性还是原型属性,都输出 true,除非“abc”既不是实例属性也不是原型属性(boolean值)
if(_user.hasOwnProperty("abc")){
alert("该属性是实例属性");
}else{
alert("该属性是原型属性");
}
}
}
main();