论坛首页 Web前端技术论坛

你能写出来吗,严格判断对象是否是WINDOW,JQ的判断暴弱了

浏览 14851 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-10-08  
satanultra 写道
function isWindow(obj) {
            return Object.prototype.toString.call(window) == Object.prototype.toString.call(obj);
        }



//IE
alert(isWindow(document)) //true



0 请登录后投票
   发表时间:2011-10-09  
。。。仰望
0 请登录后投票
   发表时间:2011-10-10  
以下是我的Fan框架中使用的判断window方式

/**
 * @staticMethod isWindow(win) 判断传入的对象是否为window对象
 */
Fan.isWindow = (function(){
    var f = function(w){return w == this || w == top;};
    return function(w){
        var r = false;
        if(f(w)) return true;
        var i = 0;
        while(!r && w){
            if(w.parent && w.parent.frames && w.parent.frames.length > i){
                r = w == w.parent.frames[i++].window;
            }else{
                if (w === w.parent) return false;
                r = false;
                i = 0;
                w = w.parent;
            }
        }
        return r;
    };
})()



javascript 框架:Fan v1.3.27
特点:让你用java编码方式,编写javascript。
已经实现了OOP的基本特征:封装、继承、多态。

关键字:
1、clazz 定义类:
犹如在java或C#中一样,包名 + 类名 + 实现体 <===> 完整类名 + 实现体。
 Fan.package('com.aaa.bbb');//声明命名空间
 Fan.clazz('com.aaa.bbb.Test', function(){
  var _d;
  // 构造方法,new Test()时,会自动调用构造方法来构造Test实例
  this.Test = function(d){
  this.$super();
  _d = d;
  };
  this.show = function(){
  return _d;
  };
  });


3、interface 定义接口:
接口定义规则:
(1)不允许出现逻辑代码
(2)所有方法成员全等于Function
(3)所有非Function均为静态属性成员
Fan.package('com.aaa.bbb');
Fan.interface('com.aaa.bbb.ICreate', function(){
  this.INFO = 'create interface';
  this.show1 = Function;
  this.show2 = Function;
  });


4、$super 指向父类对象及父类构造方法
 Fan.package('com.aaa.bbb');
 Fan.clazz('com.aaa.bbb.Test', function(){
  var _d;
  this.Test = function(d){
  // 构造方法显示调用父类构造方法,必须放在首句
  this.$super(d); 
  _d = d;
  };
  this.toString = function(){
  // $super 指向真实的父类对象并调用其toString方法
  return this.$super.toString() + _d;
  };
  });


5、类继承:
 Fan.package('com.aaa.bbb');

 /* 引入包中的类,当类从未被加载过,则该操作会发ajax从server端拉取js文件
  * improt第二参数可指定是否公开Test类,默认true
  */
 Fan.improt('com.aaa.bbb.Test');
 
 // 被继承的类,写在子类的类名后面,当improt第二参数为false时,父类需要写完整类名:com.aaa.bbb.Test, 缺省时继承Object
Fan.clazz('com.aaa.bbb.DemoTest', Test, function(){
  var _name;
  this.DemoTest = function(name){
  // 构造方法显示调用父类构造方法,必须放在首句
  this.$super(123); 
  _name = name;
  };

  this.getName = function(){
  return _name
  };
  });


6、接口继承:多重继承
 Fan.package('com.aaa.bbb');
 Fan.improt('com.aaa.bbb.ICreateA');
 Fan.improt('com.aaa.bbb.ICreateB');
 // 参数起始位置2 至 倒数第二个位置,属于可变长度,传多个接口,或者一个接口数组
 Fan.interface('com.aaa.bbb.ICreateC', ICreateA, ICreateB, function(){
  this.INFO = 'Fan.test.IC';
  this.showC = Function;
  });

 Fan.interface('com.aaa.bbb.ICreateC', [ICreateA, ICreateB], function(){
  this.INFO = 'Fan.test.IC';
  this.showC = Function;
  });



7、实现接口:
 //实现类需要实现接口中所有方法,否则将会得到警告,调用未实现的方法将得到异常
 Fan.package('com.test');
 Fan.improt('com.aaa.bbb.Test');
 Fan.improt('com.aaa.bbb.ICreateA');
 Fan.improt('com.aaa.bbb.ICreateB');
 Fan.clazz('com.test.TestA', Test, ICreateA, ICreateB, function(){
  this.a = null;
   
  this.TestA = function(cfg){
  this.$super(cfg);
  this.a = cfg.a || 'Test.a';
  };
   
  this.showA = function(){
  return this.a;
  };
  });


8、派生对象类型鉴别
var sub = new TestA();
sub instanceof TestA // true
sub instanceof sub.getClass() // true
sub instanceof Test // true
sub instanceof sub.getClass().superClass // true
sub instanceof Object // true
sub instanceof sub.$super.getClass() // true
sub.$super instanceof Test // true
sub.$super instanceof sub.getClass().superClass // true
sub.getClass().superClass === sub.$super.getClass() // true
sub.$super.$super instanceof Object // true


9、OOP辅助函数:
Fan命名空间下:
isClass、isInterface、isPackage、isPrivatePackage、instance(接口派生对象专用鉴别方法)、improt、deferImprot ...

10、扩展类库:
Fan.net.Ajax
Fan.util.Map
Fan.util.Logger
Fan.util.Cached
Fan.cmd.Command
Fan.cmd.CommandListener
Fan.cmd.KeyPressListener
Fan.cmd.MouseListener
Fan.Element/Fan.Elements
Fan.Browser
...


11、选择器,支持部分CSS选择器,与JQ性能对比,相差不多,且尚有优化的空间
样例:
Fan('#id');
Fan('.class');
Fan('div');
Fan('.test[name^=div1]');
Fan('div[name$=1]');
Fan('.test div[anme!=div1]');
Fan('div > span[name~=div1]');
Fan('div > span > div > table > tbody > tr > td > div');
Fan('.test span > div table td > div[name=innerDiv1]');


Fan v1.3.27 API:
临时地址(21:00-24:00):
http://diky87688973.gicp.net:8080/fan/fan_v1.3.27/doc/index.html

Fan API将持续更新...
0 请登录后投票
   发表时间:2011-10-11  
diky87688973 写道
以下是我的Fan框架中使用的判断window方式


var isWindow = (function(){  
    var f = function(w){return w == this || w == top;};  
    return function(w){  
        var r = false;  
        if(f(w)) return true;  
        var i = 0;  
        while(!r && w){  
            if(w.parent && w.parent.frames && w.parent.frames.length > i){  
                r = w == w.parent.frames[i++].window;  
            }else{  
                if (w === w.parent) return false;  
                r = false;  
                i = 0;  
                w = w.parent;  
            }  
        }  
        return r;  
    };  
})();
var wi={ parent : { frames : [ {} ] } };
wi.parent.frames[0].window = wi;
alert(isWindow(wi)) //true
0 请登录后投票
   发表时间:2011-10-11   最后修改:2011-10-11
zeroneta 写道
diky87688973 写道
以下是我的Fan框架中使用的判断window方式


var isWindow = (function(){  
    var f = function(w){return w == this || w == top;};  
    return function(w){  
        var r = false;  
        if(f(w)) return true;  
        var i = 0;  
        while(!r && w){  
            if(w.parent && w.parent.frames && w.parent.frames.length > i){  
                r = w == w.parent.frames[i++].window;  
            }else{  
                if (w === w.parent) return false;  
                r = false;  
                i = 0;  
                w = w.parent;  
            }  
        }  
        return r;  
    };  
})();
var wi={ parent : { frames : [ {} ] } };
wi.parent.frames[0].window = wi;
alert(isWindow(wi)) //true



你这个问题在我昨天也测试出来了,已经更改了。
Fan.isWindow = (function(){
		var f = function(w){
			if(Fan.firefox) return w instanceof window.constructor;
			else return w == this || w == top;
		};
		return function(w){
			if (!w) return false;
			if(f(w)) return true;
			var r = false, i = 0, exist = {}; // already exists
			while(w){
				if(w.parent && w.parent && w.parent.length > i){
					if (w == w.parent[i++]){
						if (exist[w.parent]) {
							exist = null;
							return false;
						}
						r = false;
						i = 0;
						w = w.parent;
						exist[w] = 1;
						if (w == w.parent && w == top) {
							exist = null;
							return true;
						}
					}
				} else return false;
			}
			return r;
		};
	})()


简洁版的:
Fan.isWindow2 = (function () {
    var f = function (c, w, i, r) {
          if (!w) return false;
          if (w == c) return true;
          while (!r && w.length > i)
              r = f(c, w[i++], 0, false);
          return r;
     };
   return function (c) {return f(c, top, 0, false);};
})();
0 请登录后投票
   发表时间:2011-10-11  
var Fan = {firefox:true};

Fan.isWindow = (function(){
		var f = function(w){
			if(Fan.firefox) return w instanceof window.constructor;
			else return w == this || w == top;
		};
		return function(w){
			if (!w) return false;
			if(f(w)) return true;
			var r = false, i = 0, exist = {}; // already exists
			while(w){
				if(w.parent && w.parent && w.parent.length > i){
					if (w == w.parent[i++]){
						if (exist[w.parent]) {
							exist = null;
							return false;
						}
						r = false;
						i = 0;
						w = w.parent;
						exist[w] = 1;
						if (w == w.parent && w == top) {
							exist = null;
							return true;
						}
					}
				} else return false;
			}
			return r;
		};
	})()

window.constructor = function(){};
var wi = new window.constructor;

//wi 是个空对象

alert(Fan.isWindow(wi)) //true
0 请登录后投票
   发表时间:2011-10-11  
zeroneta 写道
var Fan = {firefox:true};

Fan.isWindow = (function(){
		var f = function(w){
			if(Fan.firefox) return w instanceof window.constructor;
			else return w == this || w == top;
		};
		return function(w){
			if (!w) return false;
			if(f(w)) return true;
			var r = false, i = 0, exist = {}; // already exists
			while(w){
				if(w.parent && w.parent && w.parent.length > i){
					if (w == w.parent[i++]){
						if (exist[w.parent]) {
							exist = null;
							return false;
						}
						r = false;
						i = 0;
						w = w.parent;
						exist[w] = 1;
						if (w == w.parent && w == top) {
							exist = null;
							return true;
						}
					}
				} else return false;
			}
			return r;
		};
	})()

window.constructor = function(){};
var wi = new window.constructor;

//wi 是个空对象

alert(Fan.isWindow(wi)) //true



晕了。这是恶意行为。。。一般都不会去修改window属性。
你用我另一个简洁版的试试:
Fan.isWindow2 = (function () {
    var f = function (c, w, i, r) {
          if (!w) return false;
          if (w == c) return true;
          while (!r && w.length > i)
              r = f(c, w[i++], 0, false);
          return r;
     };
   return function (c) {return f(c, top, 0, false);};
})()
0 请登录后投票
   发表时间:2011-10-11  
var wi = {};
wi[0] = wi;
wi.parent = wi;
wi.length = 1;
window.top = wi;

alert(Fan.isWindow(wi)) //true
0 请登录后投票
   发表时间:2011-10-11  
var isWindow2 = (function () { 
    var f = function (c, w, i, r) { 
          if (!w) return false; 
          if (w == c) return true; 
          while (!r && w.length > i) 
              r = f(c, w[i++], 0, false); 
          return r; 
     }; 
   return function (c) {return f(c, top, 0, false);}; 
})()

var wi = {};
wi[0] = wi;
wi.parent = wi;
wi.length = 1;
window.top = wi;

alert(isWindow2(wi)) //true
0 请登录后投票
   发表时间:2011-10-11   最后修改:2011-10-11
zeroneta 写道
var isWindow2 = (function () { 
    var f = function (c, w, i, r) { 
          if (!w) return false; 
          if (w == c) return true; 
          while (!r && w.length > i) 
              r = f(c, w[i++], 0, false); 
          return r; 
     }; 
   return function (c) {return f(c, top, 0, false);}; 
})()

var wi = {};
wi[0] = wi;
wi.parent = wi;
wi.length = 1;
window.top = wi;

alert(isWindow2(wi)) //true



top都改。。。
(function(top, window, document, undefined){
   Fan.isWindow = (function () { 
	    var f = function (c, w, i, r) {
	          if (!w) return false;
	          if (w == c) return true;
	          while (!r && w.length > i)
	              r = f(c, w[i++], 0, false);
	          return r;
	     }; 
	   return function (c) {return c == window || c == top || f(c, top, 0, false);};
	})();
})(top, window, document);


还能找到bug么?
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics