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-高级进阶

day03-JavaScript高级 1、js的函数定义(三种方式)  一、使用关键字  function 方法名称(参数列表) { 方法体和返回值 }          注意1:参数列表中的参...
  • tujunyong
  • tujunyong
  • 2016年11月29日 23:50
  • 1293

JavaScript进阶学习(一)

学习了JavaScript基础语法,感觉掌握还不够,所以正在看:JavaScript高级程序设计。本书很基础,又有高级特性部分,深入浅出,值得一看 历史就不记了,一大堆 JavaScript事一种...
  • qq_24558789
  • qq_24558789
  • 2016年12月19日 16:26
  • 213

Hadoop入门进阶步步高(一)-环境准备

前言Hadoop从存储上来说,是类似于冗余磁盘阵列(RAID)的存储方式,将数据分散存储并提供以提供吞吐量,它的存储系统就是HDFS(Hadoop Distuibute Fils System);从计...
  • fenglibing
  • fenglibing
  • 2014年06月15日 21:53
  • 9158

JS进阶书籍

本来想尝试每天回答或看已解决的3个问题来学习总结今天的知识点,看了下博文里面的问答,在问的和已解决的都提不起兴趣。就看了下知识库里面一些文章,把里面感觉好的段落再摘录一下,为自己再看时备忘。 ...
  • bingqingsuimeng
  • bingqingsuimeng
  • 2014年10月28日 09:01
  • 6132

JS高级进阶之征服异步编程

轻松一下问大家一个问题,JS为什么是单线程? 也许有些人知道,但是我要说的是有趣的事情,创造JS的网景公司拒绝别人向浏览器里加入线程的提议,原因是如果加入了线程,这门语言的推广就没有那么成功了,J...
  • AndyNikolas
  • AndyNikolas
  • 2017年06月05日 22:12
  • 334

JavaScript进阶学习——JavaScript内置对象

JavaScript内置对象 1什么是对象 2Date日期对象 3返回设置年份的方法 4返回星期的方法 5返回设置时间的方法 6String字符串对象 7返回指定位置的字符 8返回指定的字符串首次出现...
  • SungLee_1992
  • SungLee_1992
  • 2016年11月04日 14:41
  • 360

js进阶篇

JS进阶篇 web前端开发师需要掌握什么技术?允许你已经了解HTML标记(也成为结构)知道了css样式(也称为表示)会用html和css创建一个漂亮的页面,但是这个还是不够,它只是静态的页面而已,我们...
  • zxcSabrina
  • zxcSabrina
  • 2016年08月25日 13:51
  • 1686

面向对象的JavaScript(2): 对象就是二元组

什么是对象?这里有很多关于对象的定义:对象(object)是一件事、一个实体、一个名词,是可以获得的东西,是可以想象的能够有自己标识的任何东西。对象是类的实例化。对象是一些相关的变量和方法的软件集合。...
  • FinderCheng
  • FinderCheng
  • 2009年04月21日 20:42
  • 1312

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

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

JavaScript深入浅出(进阶)

JavaScript进阶 ---许多 来源于慕课网教学视频,如侵删。
  • qq_35893033
  • qq_35893033
  • 2017年08月23日 07:27
  • 124
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript进阶(二)
举报原因:
原因补充:

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