javaScript:3天理解面向对象(1)

面向对象:

什么是对象?
  - 对象就是对事物的描述,简单来说世界上的任何物质都是对象(万物皆对象)-日月星辰、花草树木、飞禽走兽;   
什么是面向对象?
  - 把数据以及数据的操作方法放到一起,形成相互依存的整体,然后把这些 数据中具有相同特征的抽取出来,形成类。通过封装隐藏内部细节,通过继承实现类的特化,  通过多态实现基于对象类型的动态分派;<Milo Yi在知乎上的回答> 
以人为例进行对象的描述(对象的描述就是:属性+方法):
  -人的特征:   -属性:身高,体重,家庭背景;   -方法:吃饭,唱歌,跳舞,跑步,画画,下棋。。。。   -(上面的已人为例的例子,是不是只要是个人都会做的事情,当然咱先不管他做的好还是不好。) 
那么具体的个人呢?
  1.阿大   -属性:身高150cm,体重75kg,爸妈是很有钱的人;   -方法:唱歌唱的很好,跑步跑的很快;   2.阿二:   -属性:身高170cm,体重80kg,爸妈是农民;   -方法:会跳街舞,下棋拿过奖;   (从上面来说,人的特征是不是来说,是一个共性,只要是个人就会有的特征和行为,像一个模板。阿大和阿二是个体的,他们之间有不同的差异); 
怎么用代码来表现出来呢?
function Person(height,weight,homeBack){       this.height=height;       this.weight=weight;       this.homeBack=homeBack;       this.showSigne=function(){             console.log(this.name+'我喜欢唱歌');   }      this.showDance=function(){           console.log(this.name+'我喜欢跳舞'); } } var p1=new Person('150cm','75kg','富豪'); console.log(p1.height); console.log(p1.weight); p1.showSigne(); var p2=new Person("170cm","80kg","农民"); console.log(p2.height); console.log(p2.weight); p2.showDance(); -从上面可以看出Person这个函数,像一个模板似的,把人的所有的属性和行为全部记录下来(我们把它称为构造函数);p1,p2是Person这个函数的具体个例(我们把它称为实例对象); 
构造函数以及构造函数的返回值
-构造函数(模板)是抽象的;构造函数的作用就是实例化,产生一个对象; -构造函数的返回值是this,如果把构造函数的返回值设为普通的数据类型,那么它的返回值还是this,如果把构造函数的返回值设置为对象,那么它的返回值是对象; function Tag(name,age){     this.name=name;     this.age=age;     return "aa"; } var tag=new Tag("张三","19"); console.log(tag);     

输出结果:

javaScript:3天理解面向对象(1)

输出结果

  function Tag(name,age){                 this.name=name;             this.age=age;             return {                 name:'李四'             };         }   var tag=new Tag("张三","19");   console.log(tag);  

输出结果:

javaScript:3天理解面向对象(1)

1.字面量

var str="qq"; var num=222; var boolean=true; var obj={}; var arr=[1,2,34,5]; var arr=new Arry(1,2,3); var fn=new Function(); var date=new Date(); var reg=new RegExp(); 

字面量创建对象案例:

var p1={};  p1.name="张三";  p1.age=15;  p1.showName=function(){       console.log(this.name+"helloWord"); } var p2={}; p2.name="李四"; p2.age=16; p2.showName=function(){     console.log(this.name+"helloWord"); } (发现通过字面量创建出来的实例对象,代码冗余度比较高,不可取。) 

2.通过构造函数实例化对象

系统中提供的构造函数
var obj=new Object();
var arr=new Array();
var date=new Date();
var reg=new RegExp();
var str=new String();
var num=new Number();
var boole=new Boolean();
var fn=new Function();

function Person(){     this.name=name;     this.age=age;     this.showName=function(){         console.log(this.name+"helloWord");  } } var p1=new Person("张三",16); var p2=new Person("赵四",18); (通过构造函数实例化出来的对象代码简洁,后期可维护性更高);  (实例对象包含一系列键值对,键是字符串,值可以是任意的数据类型);  看个案例:   var obj={};   obj.list={       ids:[{           name:"张三",           age:15,           scoa:[1,2,34,12,7] }]         }; (这个案例充分说明了实例对象的的内容都是键值对,键是字符串,值可以是任意的数据类型) 
作业:以老虎为例创建一个构造函数并实例化出来两只老虎

答案:

    function Tag (name,color,hobby) {             this.name=name;             this.color=color;             this.hobby=hobby;             this.showName=function  () {                 console.log(this.name+":我喜欢踢球!")             }             this.showAge=function  () {                 console.log(this.name+":我喜欢跑步!")             }         }           var tag1=new Tag("小白","白色","跳舞");         var tag2=new Tag("小黄","黄色","画画"); 
实例对象的访问方式

用.访问
tag1.name;
tag1.showName();
用[]访问
tag1[”name’];
tag1‘showName’;

基本类型和引用类型
console.log(tag1.showName==tag2.showName)//false; console.log(tag1.showAge===tag2.showAge)//false; (为什么会不相等呢?) 因为引用类型比较的是内存地址; 

这是一张引用类型的内存图:

javaScript:3天理解面向对象(1)

从图中可以知道,内存分为栈空间和堆空间;栈空间存储变量名然后返回一个内存地址;

解析:tag1和tag2是Tag的两个实例,从图中可以看出内存的分布状态,线1和线2分别指向堆内存中开辟的空间。构造函数中的方法也在堆内存中开辟出两个空间。那假如这样来说假如构造函数有100个实例对象,那么就要在堆内存中开辟100个方法空间,从某种意义上说,这是不是浪费了内存空间?我们该怎么去解决这个问题呢?

prototype

我们通过prototype来解决空间冗余的问题;

每个构造函数都有一个prototype属性,这个属性默认 是Object的实例(或者{}的实例),prototype有两个属性proto和constructor,prototype中的属性和方法被实例对象所共享;

案例:

    function Tag (name,color,hobby) {             this.name=name;             this.color=color;             this.hobby=hobby;         }         Tag.prototype.showName=function  () {             console.log(this.name+":helloWord!")         }
 var tag1=new Tag("小白","白色","跳舞");         var tag2=new Tag("小黄","黄色","画画");         console.log(tag1.showName==tag2.showName);         console.log(tag1.showName===tag2.showName); 

结果为:

javaScript:3天理解面向对象(1)

这是面向对象的最小案例:

<!DOCTYPE html> <html> <head>     <meta charset="UTF-8">     <title></title>     <style type="text/css">         div{             background: red;             border: 1px solid #ccc;             width: 100px;             height: 100px;         }     </style> </head> <body>     <button id="btn">点击</button>     <div id="div1"></div>     <script type="text/javascript">         function Foo (div1,btn) {             this.div1=document.getElementById(div1);             this.btn=document.getElementById(btn);         }            Foo.prototype.innit=function () {             var _this=this;             this.btn.onclick=function  () {                 _this.changeStyle(this);             }         }         Foo.prototype.changeStyle=function  (that) {             this.div1.style.width="200px";             this.div1.style.heigth="200px";             this.div1.style.background='yellow';             that.style.background='red';         }         var c1=new Foo('div1','btn');         c1.innit();     </script> </body> </html>