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"
posted @ 2012-09-10 19:00  @电动小马达  阅读(112)  评论(0)    收藏  举报