JQuery 构造和面向对象的杂记
面向对象语言的要求
一种面向对象语言需要向开发者提供四种基本能力:
封装 - 把相关的信息(无论数据或方法)存储在对象中的能力
聚集 - 把一个对象存储在另一个对象内的能力
继承 - 由另一个类(或多个类)得来类的属性和方法的能力
多态 - 编写能以多种方法运行的函数或方法的能力
ECMAScript 支持这些要求,因此可被是看做面向对象的。
基本的链式调用的实现
(function(){ var Dog=function(name,age){ if(!(this instanceof Dog)){ return new Dog(name,age); } this.name = name; this.age = age; }; Dog.prototype={ getName:function(){ console.log(this.name); return this; }, getAge:function(){ console.log(this.age); return this; } }; return (window.Dog=Dog); })(); Dog("旺旺",3).getName().getAge();
or
(function(){ var Dog=function(name,age){ this.name = name; this.age = age; }; Dog.prototype={ getName:function(){ console.log(this.name); return this; }, getAge:function(){ console.log(this.age); return this; } }; window.Dogs=function(name,age){ return new Dog(name,age); }; })(); Dogs("旺旺",3).getName().getAge();
jQuery 构造的核心 在果神的帮助下俺终于把这部分看明白了,感觉这部分代码好逆天哇(之前用的是美,现在觉得逆天比较好吧);
(function(a,undefined){ var doc = window.document, loc = window.location, nav = window.navigator; var jQuery = function(selector){ return new jQuery.fn.init(selector); } jQuery.fn = jQuery.prototype = { constructor: jQuery, init :function(selector){ var element = document.getElementById(selector); this.length = 1; this[0] = element; return this; }, length : 0, splice: [].splice }; jQuery.fn.init.prototype = jQuery.fn; //这里算是一个继承么? jQuery.extend = jQuery.fn.extend = function(o) { return this; } window.Dirt = window.$ = window.jQuery = jQuery; //for amd,amd jQeury 对amd的支持,至于amd是个啥我也不知道,请自行百度吧,从百科的描述来看,这玩意是个好东东 if ( typeof define === "function" && define.amd && define.amd.jQuery ) { define( "jquery", [], function () { return jQuery; } ); } })(window);
关于jQuery的extend的简单实现
jQeury 中的extend要比这个要复杂一点,当前例子仅实现了基本的对类和对象的简单扩展,并且没有做太多的防御性和控制性的判断,另外$.each方法和jQuery的实现不太一样,是按照自己的理解来做的,jQuery的each好绕,我没看懂;
jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { var target , copy ,src ,deep , options , name; options = arguments[0]; target = this; for (name in options ) { target[name] = options[name]; }; return target; } window.D = window.Dirt = jQuery; /*通过上面的extend 对 jQuery.fn 和 jQuery 类进行扩展 */ D.extend({ 'demo':function(){ console.log('demo1') }, 'demo2':function(){ console.log('demo2') } }); D.demo(); D.fn.extend({ 'show':function(){ this.each(function(){ this.style.display = ''; }) return this; }, 'hide':function(){ this.each(function(){ this.style.display = 'none'; }) return this; }, 'css' : function(key,value){ this.each(function(){ if(typeof key == 'object'){ for(var name in key){ this.style[name] = key[name]; } }else if(typeof key == 'string'){ this.style[key] = value; } }); return this; } }); D('s1').css('background','#f00').css({'background':'#f00','height':'10'});
$.parseJSON()的实现
//(new Function( 'return {"key" : "value"}'))(); D.extend({ 'parseJSON':function(data){ if ( window.JSON && window.JSON.parse ) { return window.JSON.parse( data ); }else{ return ( new Function( 'return ' + data ) )(); //注意这句,这个例子只是基本思路,实际上要对data的字符串里面的' " 双引号进行处理 } } });
new Function() 详见权威指南第8章函数,最后一节
/*这是一个挺实用的技巧,好于eval 去解析json */ new Function('x','y','return x * y;'); /* 等同于下面的方法 */ function f(x,y){ return x * y ;}
将类数组对象转成真实数组的另外一个技巧 :
var A ; function add(param1,param2){ console.log(arguments); var array= Array.prototype.slice.call(arguments); //实际上这条语句的效率很慢,不推荐使用(js 秘密花园) A = array; } add('1','2');
instanceof 运算符
function Person(){ console.log(this instanceof Person) } var p1 = new Person();
isPrototypeOf()
range.methods.isPrototypeOf(r);
constructor 属性
另一种识别对象是否属于某个类的方法是使用construtor属性,因为构造函数是类的公共标识,所以最直接的方法就是使用constructor属性。
hasOwnProperty(property)
判断对象是否有某个特定的属性。必须用字符串指定该属性。(例如,o.hasOwnProperty("name"))
IsPrototypeOf?(object) 判断该对象是否为另一个对象的原型。
PropertyIsEnumerable? 判断给定的属性是否可以用 for...in 语句进行枚举。
设计模式:工厂模式
创建一个汽车的实例 原始模式:
var oCar = new Object; oCar.color = "blue"; oCar.doors = 4; oCar.mpg = 25; oCar.showColor = function() { alert(this.color); };
解决方案 :工厂模式
function createCar() { var oTempCar = new Object; oTempCar.color = "blue"; oTempCar.doors = 4; oTempCar.mpg = 25; oTempCar.showColor = function() { alert(this.color); }; return oTempCar; } var oCar1 = createCar(); var oCar2 = createCar();
构造函数方式
创建构造函数就像创建工厂函数一样容易。第一步选择类名,即构造函数的名字。根据惯例,这个名字的首字母大写,以使它与首字母通常是小写的变量名分开。除了这点不同,构造函数看起来很像工厂函数。请考虑下面的例子:
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.showColor = function() { alert(this.color); }; } var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25);
原型方式
function Car() { } Car.prototype.color = "blue"; Car.prototype.doors = 4; Car.prototype.mpg = 25; Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car(); var oCar2 = new Car();
混合的构造函数/原型方式 ==
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike","John"); } Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25); oCar1.drivers.push("Bill"); alert(oCar1.drivers); //输出 "Mike,John,Bill" alert(oCar2.drivers); //输出 "Mike,John"

浙公网安备 33010602011771号