面向对象的编程(1)

一.什么是面向对象编程

1.用对象的思想去写代码,就是面向对象编程

我们以前常用的编程方式可以是比较过程式的写法,定义变量,然后给变量添加各种事件,如编写一个简单的选项卡,这样的写法有一个缺点,那就是复用性不高,假如页面上不止一个选项卡,那么同样的代码可能要出现很多次。

2.其实我们一直在使用对象

我们平时使用的Array,Date都是系统的内置对象

3.面向对象编程的特点,也可以说是优势:

1)抽象:抓住核心问题

2)封装:只能通过对象来访问方法

3)继承:从已有对象上继承出新的对象(代码复用)

4)多态:多对象的不同形态(同样是代码复用的方式,但是使用的比较少)

4.对象的组成

对象由属性和方法组成

对象下面的变量我们称之为属性,对象下面的函数我们称之为方法

二、创建第一个面向对象程序

var obj = new Object();  //创建了一个空的对象
//给对象添加属性和方法
obj.name = '小明';  //属性
obj.showName = function(){  //方法
    alert(this.name);
};

obj.showName();

其实这就是一个完整的面向对象程序了,看起来是不是很简单~

假设我们现在需要创建另外一个对象,那么我们只需要把代码再复制一遍,但是这样又有问题了,因为代码看起来不够优化,之前学习js的时候,学习到的思想就是如果有重复的代码,那么我们尽量把它封装成一个函数;在面向对象中,同样可以,只不过不叫封装函数了,我们称之为“工厂方式”。

function CreatePerson(name){
    
    //1.原料
    var obj = new Object();
    //2.加工
    obj.name = name;
    obj.showName = function(){
        alert( this.name );
    };
    //3.出厂
    return obj;
    
}

var p1 = new CreatePerson('小明');
p1.showName();
var p2 = new CreatePerson('小强');
p2.showName();

这样看起来是不是简洁很多。

这里有两个新的概念,我们知道,其实我们在调用函数的时候,是可以直接调用的,像这样:

var p1 = CreatePerson('小明');

那么前面加上new,又有什么区别呢?

当new去调用一个函数 : 这个时候函数中的this就是创建出来的对象,而且函数的的返回值直接就是this(隐式返回)

另外new后面调用的函数 : 叫做构造函数

用来创建对象的函数,我们称之为构造函数。构造函数的特点:

1)首字母大写(参考系统对象写法)

2)New 关键字提取

3)This指向为新创建的对象

代码这样写同样还是存在问题,因为每创建一个对象,都要去创建一个方法,尽管这个方法做的是同一件事情,这样会造成内存浪费。

我们知道每一个对象都是有原型的,假设我们把方法加在原型上,那由原型构造的每一个对象就都拥有这个方法了。

function CreatePerson(name){ 
    this.name = name; 
}
CreatePerson.prototype.showName = function(){
    alert( this.name );
};

var p1 = new CreatePerson('小明');
p1.showName();
var p2 = new CreatePerson('小强');
p2.showName();

这样的话相同的方法在内存中就只存在一份了。

我们来总结一下面向对象的写法:

构造函数加属性,原型加方法

function 构造函数(){
    this.属性
}

构造函数.原型.方法 = function(){};

var 对象1 = new 构造函数();
对象1.方法();

三、面向对象编程实践(1)-选项卡改写

1.原则:先写出普通的写法,然后改成面向对象写法

1)普通方法变型
  • 尽量不要出现函数嵌套函数

  • 可以有全局变量

  • 把onload中不是赋值的语句放到单独函数中

2)改成面向对象
  • 全局变量就是属性

  • 函数就是方法

  • Onload中创建对象

  • 改this指向问题(事件和定时器中this指向容易被修改)

普通写法:

html和css代码就不贴了

window.onload = function(){
    var oWrap = document.getElementById('wrap');
    var aBtn = document.getElementsByTagName('input');
    var aDiv = oWrap.getElementsByTagName('div');
    for (var i = 0; i < aBtn.length; i++) {
        aBtn[i].index = i;
        aBtn[i].onclick = function () {
            for (var i = 0; i < aDiv.length; i++) {
                aBtn[i].className = "";
                aDiv[i].style.display = "none";
            }
            aDiv[this.index].style.display = "block";
            aBtn[this.index].className = "active";
        };
    }
}

根据改写原则变形

var oWrap = null;
var aBtn = null;
var aDiv = null;

window.onload = function(){
    
    oWrap = document.getElementById('wrap');
    aBtn = oWrap.getElementsByTagName('input');
    aDiv = oWrap.getElementsByTagName('div');

    init();
    
};
//初始化函数
function init(){

    for(var i=0;i<aBtn.length;i++){
        aBtn[i].index = i;
        aBtn[i].onclick = change;
    }

}

function change(){

    for(var i=0;i<aBtn.length;i++){
        aBtn[i].className = '';
        aDiv[i].style.display = 'none';
    }

    this.className = 'active';
    aDiv[this.index].style.display = 'block';

}

呃。。改写之后好像更复杂了

继续改

function Tab(id) {
    this.oWrap = document.getElementById(id);
    this.aBtn = this.oWrap.getElementsByTagName('input');
    this.aDiv = this.oWrap.getElementsByTagName('div');
    this.iNow = 0;
}

Tab.prototype.init = function() {
    var that = this;

    for (var i = 0; i < that.aBtn.length; i++) {
        that.aBtn[i].index = i;
        that.aBtn[i].onclick = function () {
            that.change(this);
        };
    }

};

Tab.prototype.change = function(obj) {

    for (var i = 0; i < this.aDiv.length; i++) {
        this.aBtn[i].className = "";
        this.aDiv[i].style.display = "none";
    }

    this.aDiv[obj.index].style.display = "block";
    obj.className = "active";

};
var t1 = new Tab("wrap"); //传参是为了方便复用
t1.init();//没用window.onload,那就写在后面,否则无法调用

这里this、that傻傻分不清的,请看这里:函数进阶

这样看起来虽然还是没有普通写法简单,但是如果要复用的话就方便多了,另外面向对象编程比较适用于复杂的项目。

假如页面上还有另外一个选项卡,而且这个选项卡要求是自动播放的,那么我们只需要在原来的基础上加上:

Tab.prototype.autoPaly = function () {

    var that = this;

    setInterval(function() {
        if(that.iNow == that.aBtn.length-1){
            that.iNow = 0;
        }
        else{
            that.iNow++;
        }
        for (var i = 0; i < that.aDiv.length; i++) {
            that.aBtn[i].className = "";
            that.aDiv[i].style.display = "none";
        }
        that.aDiv[that.iNow].style.display = "block";
        that.aBtn[that.iNow].className = "active";

    }, 2000);

};
var t2 = new Tab("wrap2");
t2.init();
t2.autoPaly();

四、面向对象编程实践(2)-拖拽改写

这里要特别注意一下event对象的位置。

window.onload = function () {
    var d1 = new Drag('div1');
    d1.init();
};
//构造函数Drag
function Drag(id) {
    this.oDiv = document.getElementById(id);
    this.disX = 0;
    this.disY = 0;
}
//初始化方法
Drag.prototype.init = function () {

    var that = this;

    this.oDiv.onmousedown = function (e) {
        e = e||window.event; //event只能出现在事件函数当中,所以不能写在fnDown方法里面
        that.fnDown(e);
        return false;
    };


};
Drag.prototype.fnDown = function(e) {
    var that = this;

    this.disX = e.clientX - this.oDiv.offsetLeft;
    this.disY = e.clientY - this.oDiv.offsetTop;

    document.onmousemove = function(e){
        e = e||window.event;
        that.fnMove(e);
    };

    document.onmouseup = this.fnUp;//注意这里别加括号。。踩过的坑
};

Drag.prototype.fnMove = function(e) {
    this.oDiv.style.left = e.clientX - this.disX +'px';
    this.oDiv.style.top = e.clientY - this.disY + 'px';
};

Drag.prototype.fnUp = function() {
    document.onmousemove = null;
    document.onmouseup = null;
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容