面向对象及组件开发---笔记1

1、什么是面向对象编程
•用对象的思想去写代码,就是面向对象编程
  • 过程式写法
  • 面向对象写法
过程式写法如下
function test(){} for(){} if(){}

• 我们一直都在使用对象

如数组 Array  时间 Date都是对象
//创建
var arr = new Array(); //[] ,底下分别有些方法
var date = new Date(); //arr的方法
arr.length arr.push(); arr.sort(); //date的方法
date.getDate();
我们把系统自带的对象,叫做系统对象
• 面向对象编程(OOP)的特点  最好的学习方法就是多练习
  • 抽象:抓住核心问题 抽是抽取,象是具象
  • 封装:只能通过对象来访问方法
  • 继承:从已有对象上继承出新的对象  其实就是复用代码
  • 多态:多对象的不同形态  复用的另外一种形式,但是用的不多,因js语言是弱类型类型

• 对象的组成

  • 方法(行为、操作)——函数:过程、动态的
  • 属性——变量:状态、静态的
属性和方法的区别
//系统对象下的数组
var arr = [];//对象
arr.number = 10;  //对象下面的变量:叫做对象的属性 //alert( arr.number ); //alert( arr.length );
arr.test = function(){  //把一个函数写在对象下面,或者说对象下面的函数 : 叫做对象的方法
    alert(123); }; arr.test(); //以下是常见的方法,加括号的是方法,不加是属性
arr.push(); arr.sort();

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

    •为对象添加属性和方法
       –Object对象
        –this指向
        –创建两个对象 : 重复代码过多

 以下是一个完成的面向对象的程序

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

面向对象中难点this指向,谁调用的就是指向谁

3.工厂方式与构造函数

工厂方式 其实就是封装函数

1.面向对象中的封装函数

  • //工厂方式 : 封装函数
    function creatName(name){ //1.原料
        var obj=new Object(); //2.加工
        obj.name=name; obj.showName=function(){ alert( this.name ); //此时this的指向是window } //3.出场
        return obj; } var p1 = creatName('小明');//创建对象
    p1.showName();             //调用方法
    var p2 = creatName('小强'); p2.showName();

2.改成与系统对象类似写法

    • 首字母大写
    • New 关键字提取
    • This指向为新创建的对象
//当new去调用一个函数 : 这个时候函数中的this就是创建出来的对象,而且函数的的返回值直接就是this啦(隐式返回)
//new后面调用的函数 : 叫做构造函数
function CreatePerson(name){ this.name = name; this.showName = function(){ alert( this.name ); }; } var p1 = new CreatePerson('小明'); p1.showName();
var p2 = new CreatePerson('小强'); p2.showName();
 alert( p1.showName == p2.showName );  //false 
3.构造函数的定义
  • 用来创建对象的函数,叫做构造函数
4.存在的问题
  • 对象的引用
  • 浪费内存

为什么p1和p2是false,这和类型的传递有关,内存和值都相等才相等

 基本类型 : 赋值的时候只是值的复制
var a = 5; var b = a; b += 3; alert(b); //8
alert(a); //5 基本类型 : 赋值的时候只是值的复制
对象类型 : 赋值不仅是值的复制,而且也是引用的传递
var a = [1,2,3]; var b = a; b.push(4); alert(b); //[1,2,3,4]
alert(a);  //[1,2,3,4] 对象类型 : 赋值不仅是值的复制,而且也是引用的传递
var a = [1,2,3]; var b = a; b = [1,2,3,4]; alert(b); //[1,2,3,4]
alert(a); //[1,2,3]

var a = 5; var b = 5; alert(a == b);  //true基本类型 : 值相同就可以

var a = [1,2,3]; var b = [1,2,3]; alert( a == b );  //false //对象类型 : 值和引用都相同才行

var a = [1,2,3]; var b = a; alert( a==b );  //true
5.原型 :作用是去改写对象下面公用的方法或者属性 , 让公用的方法或者属性在内存中存在一份 ( 提高性能 )
3原型-prototype
 
     • 概念
 
       –重写对象方法,让相同方法在内存中存在一份(提高性能)
 
     • 学习原型
 
        –类比  :  CSS中的Class  
 
  • 原型 : CSS中的class
  • 普通方法 : CSS中的style
//CSS中的style 普通写法

var arr = [1,2,3,4,5]; var arr2 = [2,2,2,2,2]; arr.sum = function(){ var result = 0; for(var i=0;i<this.length;i++){ result += this[i]; } return result; }; arr2.sum = function(){ var result = 0; for(var i=0;i<this.length;i++){ result += this[i]; } return result; };
alert( arr.sum() );  //15
alert( arr2.sum() ); //10

    普通写法再一定情况下会代码冗长,重复

• 通过原型改写工厂方式

 
  
        –原则 
 
  
»相同的属性和方法可以加载原型上
 
  
»混合的编程模式
原型 : prototype : 要写在构造函数的下面
改写以上求和代码
var arr = [1,2,3,4,5]; var arr2 = [2,2,2,2,2]; Array.prototype.sum = function(){ var result = 0; for(var i=0;i<this.length;i++){ result += this[i]; } return result; }; alert( arr.sum() ); //15
alert( arr2.sum() );  //10

相同情况下普通写法style方式的优先级会比原型高

var arr = []; arr.number = 10; Array.prototype.number = 20; alert(arr.number); //10

   •总结面向对象写法

-----构造函数加属性,原型加方法 
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();
alert( p1.showName == p2.showName );  //true 再内存中只存在一份
面向对象的写法 按照下面的方式进行练习
<script>
function 构造函数(){ this.属性 } 构造函数.原型.方法 = function(){};

//使用
var 对象1 = new 构造函数(); 对象1.方法(); </script>

举例:面向对象的选项卡

   • 原则
           –先写出普通的写法,然后改成面向对象写法
布局
<style> #div1 div{ width:200px; height:200px; border:1px #000 solid; display:none;} .active{ background:red;}
</style>
<script>
</script>
</head>

<body>
<div id="div1">
    <input class="active" type="button" value="1">
    <input type="button" value="2">
    <input type="button" value="3">
    <div style="display:block">11111</div>
    <div>22222</div>
    <div>33333</div>
</div>
</body>
</html>

步骤一:普通写法

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

步骤二:.开始改写:原则

   》》. 普通方法变型
      • 尽量不要出现函数嵌套函数
      • 可以有全局变量 ,把局部的变成全局的变量
      • 把onload中不是赋值的语句放到单独函数中
 
  
var oParent = null; var aInput = null; var aDiv = null; window.onload = function(){ oParent = document.getElementById('div1'); aInput = oParent.getElementsByTagName('input'); aDiv = oParent.getElementsByTagName('div'); init(); }; function init(){ for(var i=0;i<aInput.length;i++){ aInput[i].index = i; aInput[i].onclick = change; } } function change(){ for(var i=0;i<aInput.length;i++){ aInput[i].className = ''; aDiv[i].style.display = 'none'; } this.className = 'active'; aDiv[this.index].style.display = 'block'; }
步骤三:»改成面向对象
  • 全局变量就是属性
  • 函数就是方法
  • Onload中创建对象 进行调用
  • 改this指向问题: 事件或者是定时器,尽量让面向对象中的this指向对象
oDiv.onclick = function(){ this : oDiv }; oDiv.onclick = show; function show(){ this : oDiv } oDiv.onclick = function(){ show(); }; function show(){ this : window }

this的指向特别容易出问题

window.onload = function(){ var t1 = new Tab(); t1.init(); }; function Tab(){ this.oParent = document.getElementById('div1'); this.aInput = this.oParent.getElementsByTagName('input'); this.aDiv = this.oParent.getElementsByTagName('div'); } Tab.prototype.init = function(){ var This = this; for(var i=0;i<this.aInput.length;i++){ this.aInput[i].index = i; this.aInput[i].onclick = function(){ This.change(this); }; } }; Tab.prototype.change = function(obj){ for(var i=0;i<this.aInput.length;i++){ this.aInput[i].className = ''; this.aDiv[i].style.display = 'none'; } obj.className = 'active'; this.aDiv[obj.index].style.display = 'block'; };

面向对象适合复杂开发,很简单的开发其实不太适合,不然反而代码更加冗长

<div id="div1">
    <input class="active" type="button" value="1">
    <input type="button" value="2">
    <input type="button" value="3">
    <div style="display:block">11111</div>
    <div>22222</div>
    <div>33333</div>
</div>

<div id="div2">
    <input class="active" type="button" value="1">
    <input type="button" value="2">
    <input type="button" value="3">
    <div style="display:block">11111</div>
    <div>22222</div>
    <div>33333</div>
</div>
window.onload = function(){ var t1 = new Tab('div1'); t1.init(); t1.autoPlay(); var t2 = new Tab('div2'); t2.init(); t2.autoPlay(); }; function Tab(id){ this.oParent = document.getElementById(id); this.aInput = this.oParent.getElementsByTagName('input'); this.aDiv = this.oParent.getElementsByTagName('div'); this.iNow = 0; } Tab.prototype.init = function(){ var This = this; for(var i=0;i<this.aInput.length;i++){ this.aInput[i].index = i; this.aInput[i].onclick = function(){ This.change(this); }; } }; Tab.prototype.change = function(obj){ for(var i=0;i<this.aInput.length;i++){ this.aInput[i].className = ''; this.aDiv[i].style.display = 'none'; } obj.className = 'active'; this.aDiv[obj.index].style.display = 'block'; }; Tab.prototype.autoPlay = function(){ var This = this; setInterval(function(){ if(This.iNow == This.aInput.length-1){ This.iNow = 0; } else{ This.iNow++; } for(var i=0;i<This.aInput.length;i++){ This.aInput[i].className = ''; This.aDiv[i].style.display = 'none'; } This.aInput[This.iNow].className = 'active'; This.aDiv[This.iNow].style.display = 'block'; },2000); };

面向对象其实就是模仿系统对象的一些行为

var arr = [4,7,1,3]; arr.sort(); // 1 3 4 7

var arr2 = [4,7,1,3]; arr2.push(5); arr2.sort(); // 1 3 4 5 7

知识点:

  1. 理解面向对象
  2. JS中对象的组成
  3. 用工厂方法创建一个对象
  4. 原型的概念和使用
  5. 修改系统对象(及原型)
  6. 混合的构造函数/原型方式

你可能感兴趣的:(面向对象及组件开发---笔记1)