javascript进阶(二)

原创 2013年12月03日 02:18:09



javascript进阶(二)

主博客:http://xiaocaoblog.diandian.com/

在建网站:http://xiaocao.sinaapp.com/

(ps:本博客适合中级javascript读者)

继上一篇javascript进阶,关于js插件开发的mvc思想,这次继续写篇博客,主要说说关于javascript的面向对象思想。


一、关于javascript类的定义

    首先,javascript是面向对象语言,但是js没有class类,而是通过:

new funName( );

来声明。

    javascript使用基于原型的语言,通过new实例化对象,其属性和行为来自两部分,原型和构造函数。

    当我们声明一个类时,同时生成了一个对应的原型。例如我们声明了:A这个类,会同时生成与这个类对应的原型。A.prototype指向原型,原型可以通过coustructor指向构造函数。写个代码你就懂。

function A(){

}

var x = A.prototype;
var y = x.constructor;
alert(y==A);    //return true;
console.log("也就是说A.prototype.constructor=A");

    当我们声明类时候,新的构造函数会把旧的prototype原型给覆盖掉。
给你看个例子。

function A(){
    this.a="属性a";
    this.b="属性b";
    this.fun1=function(){
        alert("这是函数对象1");
    };
    this.fun2=function(){
        alert("这是函数对象2");
    };
}

var B = new A();
B.fun1=function(){
    alert("你是笨蛋!!");
};

B.fun1(); //结果为alert("你是笨蛋!!");
console.log("也就是说构造函数声明的属性会覆盖原型的函数");

从上面的例子里我们可以看到,原型中的函数是会随声明的属性或者方法是会被实例化过程声明覆盖。

    一般来说,我们习惯在构造函数里放属性,在原型里面放方法。给你个例子看看:

/*===========构造函数放属性,原型里放方法============*/
function A(){
    this.a="属性a";
    this.b="属性b";
}

A.prototype={
    fun1:function(){
        console.log("这是函数对象1,我们把它放在原型里");
    },
    fun2:function(){
        console.log("这是函数对象2,我们同样也把它放在原型里");
    }
};

var B = new A();
B.fun1();
B.fun2();
console.error("这样就整洁多了。");



二、公有和私有
    js里面没有类似php一样的权限设置,可是如果我想要一个变量是私有属性怎么办?需要注意的一点是,只要写在原型里的不管是属性还是方法,都是公有性的。所以要怎样才能让一个变量私有化呢?看看例子:

/*===============原型中的共有域和私有域================*/
function A(){
    var a="属性a是私有的,在类外面你是调用不到的。";
    this.b="属性b是公有的";

    var fun1=function(){
        console.log("函数对象1是私有的,在类外面你是调用不到的。");
    };
    this.fun2=function(){
        console.log("函数对象2是共有的");
    };
}

A.prototype={
    fun3:function(){
        console.log("这是函数对象3,在原型里的,只能是公有的");
    }
};

var B = new A();
B.a;        //not found a;
B.b;    //返回正常
B.fun1();   //not found
B.fun2();
B.fun3();

    需要强调的一点是,原型中的属性和方法,只存在一份,是公用的,在实例化的时候,并不会在复制一遍。所以,做到了代码的重复利用,但是,如果把属性和方法都放在构造函数里,也同时导致了代码修改的麻烦。

    问题出来了,你想下,那我们如果有一个属性,很多函数都要调用他,想把它放在原型里,但是又不想把让它公有友化,怎么破?怎么破?

答案是:没法破。

于是,命名规则出来了,我们规定,在命名前对一个下划线,表示私有属性。例如:

    A.prototype={
    _value:"我们规定,这个属性为私有属性(ps:其实它就是公有的)";
};

于是有些比较倔强的码农们就提出来了一套新方案。请看:

/*=============私有与公有域==============*/
function A(){
    this.a="属性a是公有的。";
    this.b="属性b是公有的";
    this.set_a=function(value){
        this.a=value;
    };
    this.get_a=function(){
        return this.a;
    };
    this.call=function(name){
        console.log(this.get_a(name));
    };
}

var B = new A();
B.set_a("我把值改了");
B.call("a");    //return   我把值改了

看了好别扭,但是这样你就可以在属性或者方法的值改变时候,直接留下回调函数。



三、继承

     我在上一篇博客封装过关于继承的函数。因为在javascript里面没有继承,但是继承的思想又是存在于面向对象语言里。

如果没有函数,我们要怎么继承?最笨的是,类A和类B,我把A的所有属性和方法抄一遍。好傻啊,不适合。

  • 有一种想法,看看下面的代码:

    /==================关于声明中的yhis==================/

    function A(){
    this.a="属性a是公有的";
    this.b="属性b是公有的";
    }
    A.prototype={
    say:function(){
    console.log(this.a);
    }
    };

    function B(value){
    this.a=value;
    A();
    }
    var C = new B(); //你以为这么就能继承了么??天真了,试试看
    C.say(); //return undefind

哈哈,知道了吧,想知道为什么吗?

js函数调用有两种方法,

第一种是直接调用,此时,它作为函数;

第二种是通过实例化,构造函数调用;

没问题啊,但是,它们返回的this对象就不同了,第一种,作为函数调用,返回的是window对象,但是第二种调用返回的是实例对象本身。所以说不能直接调用继承。

我们把this指向改下吧:

function A(){
    this.a="属性a是公有的";
    this.b="属性b是公有的";
}   

A.prototype={
    say:function(){
        console.log(this.a);
    }
};

function B(value){
    A.call(this,value);
    A();
}

var C = new B();    //可以了
C.say();    //找到值了
  • 还有一种想法:我们试试

    /================相同原型继承==================/

    function A(){
    this.a="属性a是公有的";
    this.b="属性b是公有的";
    }

    A.prototype={
    say:function(){
    console.log(this.a);
    }
    };
    var B =function(){
    };
    B.prototype = A.prototype;
    B.prototype.test=function(){
    console.log("继承后添加的函数");
    };

    var C = new B();
    C.test(); //return console.log("继承后添加的函数");

    var D = new A();
    D.test(); //return console.log("继承后添加的函数");

为什么??为什么我只是在B中添加了test方法,但是我在A中也感染了??

因为javascript在赋值时候,如果判断出值是布尔,字符串,数值型等基本数据类型,会直接复制值,但是,赋值,数组,方法,对象等复杂数据,通常都会地址复制,所以,把A的原型也改了。

我们再试试,改回来,哪错改哪。

function A(){
    this.a="属性a是公有的";
    this.b="属性b是公有的";
}

A.prototype={
    say:function(){
        console.log(this.a);
    }
};

var B =function(){
};
B.prototype = A.prototype;
C.prototype.constructor=A;
B.prototype.test=function(){
    console.log("继承后添加的函数");
};

var C = new B();
C.test();   //return  console.log("继承后添加的函数");

var D = new A();
D.test();   //return not defind

这样就好了。


最后给下,extend的具体函数把,这样就不要一个一个地来弄了,你只要调用函数就好了。

function extend(subClass, superClass){
        var C=function(){};
        C.prototype=superClass.prototype;
        subClass.prototype=new C();
        subClass.prototype.constructor=subClass;
        subClass.superClass=superClass.prototype;
        if(superClass.prototype.constructor == Object.prototype.constructor){
            superClass.prototype.constructor=superClass;
        }
    }
    /*=====搞定了=====*/


    总结下吧。今天主要就是写了一些关于javascript面向对象的思想,还有原型和构造函数的关系。
    接下来还有最后一篇《javascript进阶(三)》,主要是一些javascript原型与底层细节分享。





写下最近的在做什么吧:

  • 看了《javascript高质量代码》;

  • 给新生培训了下,写了篇博客;

  • 看了一点点的php数据结构


写写接下来做什么吧:

  • 《python基础教程》(华哥的项目,日志分析系统)

  • 《精通android 4》(东哥)

  • 期末了,要开始复习了。


路线:手机端+web后台python+数据结构

(睡觉去。。。)


夏日小草

2013/12/3 1:57:07


JavaScript 进阶(二)变量作用域

局部变量陷阱

javascript进阶之基础篇二:对象

一、JavaScript对象: 1、对象的描述: ECMA-262 把对象(object)定义为“属性的无序集合,每个属性存放一个原始值、对象或函数”。 对象是JavaScript的基础数据类型。除...

Javascript进阶(二)

接之前的Javascript的变量及表达式,本篇文章介绍JS的数组。需要了解JS前面知识的可以参看Javascript进阶(一)。二、JS数组  在编程语言中,数组的应用非常广泛,数组的出现使得变量存...

javascript进阶(二)— — 小技巧合集

一、 == 与 ===的区别  1、==可以允许进行类型转换后进行比较   2、===只用于浅拷贝的对象进行比较,引用地址不一致则false      [12] === 12 // i...
  • mqy1023
  • mqy1023
  • 2016年05月05日 19:02
  • 299

JavaScript代码案例_进阶入门.doc

  • 2013年01月15日 19:40
  • 400KB
  • 下载

JavaScript_进阶_DOM事件处理

1.事件分类 事件冒泡:事件由最具体元素(即嵌套最深的元素)向上冒泡到最不具体的元素,从深层到浅表触发。 事件捕获:与事件冒泡相反,不太具体的节点最早接受事件,具体节点最后接收事件。Netscape只...

JavaScript入门进阶课件

  • 2013年01月10日 23:08
  • 1.09MB
  • 下载

编程实践:JavaScript进阶100例

  • 2012年04月17日 16:23
  • 59.02MB
  • 下载

你不知道的JavaScript--Item30 数组进阶全掌握

在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活、强大,不像是Java等强类型高级语言数组只...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript进阶(二)
举报原因:
原因补充:

(最多只允许输入30个字)