#继承
这是目前我们经常使用的一种继承方式,这样的方式就是我们所说的:寄生组合式继承,它是引用类型最理想的继承范式。

$.inherit = function(subClass, superClass) {
    var temp = function() {};
    temp.prototype = superClass.prototype;
    var subPro = new temp();
    subPro.constructor = subClass;
    subPro.superClass_ = superClass.prototype;
    subClass.prototype = subPro;
};

javascript主要通过原型链实现继承。
原型链的构建是通过一个类型的实例赋值给另一个构造函数的原型实现的。结果是:子类就能够访问父类的所有属性和方法。
当父类的实例属性为引用类型值,子类所有的实例会共享该属性.
这样会影响到所有实例对象。借用构造函数就是为了解决这一问题:函数只不过是在特定环境中执行代码的对象,可通过call()与apply()可以在新创建的的对象(将来)执行构造函数;即在子类构造函数的内部调用父类的构造函数;这样每个实例都会有自己的属性,并保证只使用构造函数模式来定义类,但该模式存在无法复用,将借用构造与原型链组合,为组合继承,通过借用构造函数继承实例属性,使用原型链继承共享的属性和方法,所以该继承,在对子类的实例化,都会对父类有两次实际的调用。在该寄生组合式继承,其实就是完善组合继承。实际上,我们的原型链继承只需要父类原型的一个副本,然后弥补因重写原型而失去的默认constructor属性。这样不必为了指定子类型的原型而调用父类的构造函数。

子类继承父类的原型方法,如果子类与父类方法名一样,会导致父类原型方法被重写;那么如何扩展父类原型方法,即可call()与apply()将需要拓展的父类方法指定到子类执行,然后添加需要在方法上拓展的,可通过


subPro.superClass_.**.call(this)(父类原型上的方法)

##浅析Javascript的基本类型与引用类型##

###基础类型和引用类型 ###
指针与引用区别,通俗的说,指针其实就是一个存储地址的变量,之所以叫指针,是因为习惯性的理解为:指向某个地址;而引用,就是通过指针来实现的,引用把这些麻烦的指针操作都封装起来了,只看到最终的效果。
在高级程序中,

引用类型的值是保存在内存中的对象,与其他语言不同,javascript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象,为此,引用类型的值是按引用访问的。

基本数据类型值的复制

var a=1;
var b=a;
    b=3
console.log(a);//a=1

引用类型值的复制

var a = new Object();
a.value = 1;
b = a;
b.value = 2;
console.log(a.value)//2
console.log(c)

对于引用类型,问题来了,我要是仍然要对a原来的数据进行操作?
对于引用类型的拷贝,即浅复制与深复制,用一个简单的例子加以区别。

var obj = { a:1, arr: [1,2] };
var shallowobj1 = obj;           //浅复制 
var Cloneobj2 = deepCopy(obj);  //深复制
obj.a = 2;
console.log(shallowobj1obj1.a); //输出2
console.log(Cloneobj2ob2.a);//输出1;

简单的说,浅复制会导致 obj 和 obj1 指向同一块内存地址;而深复制一般都是开辟一块新的内存地址,将原对象的各个属性逐个复制出去。如下图所示:

浅复制

###Underscore —— .clone()###
// Create a (shallow-cloned) duplicate of an object.
.clone = function(obj) {
if (!.isObject(obj)) return obj;
return
.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
这样一个方法是一种浅复制,通过源码可知是通过slice,$.extend({},obj)是通过浅复制的。还有concat也是浅复制。

深复制
JSON全局对象
var cloneObj = JSON.parse(JSON.stringify(obj));
这个能正确处理的对象只有Number,String,Boolean,Array即被json直接表示的数据结构。

###jQuery —— $.extend()###
可以通过JQuery中有$.extend()方法来完成深复制。$.extend([deep],target,object1[,objectN]) 第一个参数是可选的布尔值,表示是否进行深度合并(递归合并)。$.extend(true, {}, obj)来实现深复制。
$.Clone()的方法,但并不是用于一般引用类型的深复制,而是用于DOM对象;

jQuery.extend = jQuery.fn.extend = function() {
var src, copyIsArray, copy, name, options, clone,
    target = arguments[0] || {},
    i = 1,
    length = arguments.length,
    deep = false;

// Handle a deep copy situation
if ( typeof target === "boolean" ) {
    deep = target;

    // skip the boolean and the target
    target = arguments[ i ] || {};
    i++;
}

// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
    target = {};
}

// extend jQuery itself if only one argument is passed
if ( i === length ) {
    target = this;
    i--;
}

for ( ; i < length; i++ ) {
    // Only deal with non-null/undefined values
    if ( (options = arguments[ i ]) != null ) {
        // Extend the base object
        for ( name in options ) {
            src = target[ name ];
            copy = options[ name ];

            // Prevent never-ending loop
            if ( target === copy ) {
                continue;
            }

            // Recurse if we're merging plain objects or arrays
            if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                if ( copyIsArray ) {
                    copyIsArray = false;
                    clone = src && jQuery.isArray(src) ? src : [];

                } else {
                    clone = src && jQuery.isPlainObject(src) ? src : {};
                }

                // Never move original objects, clone them
                target[ name ] = jQuery.extend( deep, clone, copy );

            // Don't bring in undefined values
            } else if ( copy !== undefined ) {
                target[ name ] = copy;
            }
        }
    }
}

// Return the modified object
return target;
};

#构造函数
构造函数的特点

特点就是每个方法都要在每个实例上重新创建一遍。因为在javascript中,对象是按引用传值的,如果包含一些属性作为默认值,它会被所有实例共享。


构造函数的成员

私有和特权成员在函数的内部,在构造函数创建的每个实例中都会包含同样的私有和特权成员的副本,因而实例越多占用的内存越多.我们必须很清楚js中公有、私有、静态属性和方法的应用区别;这时我就会通过具体的应用场景来理解。


构造函数的属性

A.prototype属性是在构造函数上(可以理解成是构造函数的的静态属性),所以实例化的对象没有prototype的属性;所以就有了在javascript中,对象实例并没有原型。


B.用对象字面量来写对象的时候.因为属性就是静态变量,即不需要new;


C.在jquery设计中,静态与实例方法共享设计;用构造函数jQuery()的原型对象覆盖了构造函数jQuery.fn.init()的原型对象,这样构造函数jQuery.fn.init()的实例也可以访问构造函数JQuery()的原型方法和属性.

var $$ = jQuery =  function(selector) {
    return  new  jQuery.fn.init(selector);
}
jQuery.fn = jQuery.prototype ={
    name:"meihong",
    init:function(selector) {
        this.selector = selector;
        return this
    },
    constructor:jQuery
}
jQuery.prototype.init.prototype = jQuery.fn;
jQuery.fn.sayName = function() {
    return this.name;
}
console.log($$('#hellocan').sayName());

这里的ajQuery.prototype相等于一个以对象字面量形式创建新的对象,虽然结果相同,但constructor指向了Object对象,其proto指向Object对象。可通过设置constructor属性,确保该属性能够访问到适当的值。

如何将消耗内存与线程结合?