学习前端已经有一些时日,手上 的项目也在不紧不慢地进行着。之前一直想要写写博客记录下当前的学习成果,但是因了自己的惰性,迟迟未曾下笔。
今天突然发现之前学过的知识点有日渐忘记的趋势,知道自己已不再青葱年少,过目不忘。踏实点吧,如很久以前学过的谚语:好记性不如烂笔头。希望现在做笔记还不算晚。
****JavaScript 面向对象详解****
很多编程语言都是用面向对象来定义的 ,如java ,c++等主流语言 都是面向对象的程序设计 ,但是javaScript 的面向对象可能不像java 之类的强类型语言的面向对象表现的那样明显。就我个人而言对javaScript 的面向对象语言理解如下:
对象: 什么是对象?
自己之前已经学过java编程 所以 对面向对象的感觉还是比较深刻的 。当时在java当中有一句话 就是万物皆对象。当时听起来还是比较抽象的 像其4大特性之一。
后来有了更好的理解。对象我更愿意把他比喻成 黑盒子 :在不了解其内部结构的情况下,知道怎么用他表面各种操作(功能),像遥控,电视机。都可当作“对象”。
对象的特征:
抽象
抽象的意思是什么:这个问题本来就很“抽象”个人更愿意理解成 把最主要的(和问题相关的)特征“抽“取出来 意为抽象封装
个人认为这点最能体现出本人将对象比喻成”黑盒子“的原因。看不到里面的东西,不了解其内部结构,用好表面的操作。继承
从父类哪里继承一些方法和属性,子类自己又有另一些属性。
本人更愿意称之为”遗传“。多态:
这个是在java 当中面向对象的4大特性之一 ,在java中解释为 不同类的对象对同一消息做出的响应。在javascript 当中体现的不多 这里暂时不做说明。
对象的组成:
属性 与 方法
这里说明一下属性与变量的区别:
var a = [2,3,4,5];
var b = 12; //变量b
a.b=12; //属性b
alert(b);
alert(a.b)
上述例子中给a自定义b属性,两次弹窗都是12. 此例子说明 变量和属性其实是类似的
,区别在于 变量是自由的,而属性是个人的(在此申明因为javascript 不像java 那样强制类型语言所以定义属性或者变量时可以改变其属性或变量而不会报错,如 var a = 100;
var a=1000 也不会报错 );
方法 与函数也是一样
function sum(){//函数
var a = 3674;
var b = 123;
return a+b;
}
obj.sum = function(){//方法
var a = 3674;
var b = 123;
return a+b;
}
函数是自由的 但是方法是个人的。很多时候函数和方法差不多,属性和变量也差不多
在这需要提到一个关键字 this。看一下例子:
function oo(){
alert(this)
};
eg.oo = function(){
alert(this);
};
oo();
当调用oo()方法时 弹出的是window对象 但是下面的eg.oo 方法中弹出的是eg对象
由此得出 this *代表谁调用的此方法 this表示谁*
说起方法 ,不能在系统对象中随意添加方法,以免覆盖掉系统对象本身的属性及方法。
对象和类的区别
个人更愿意把”类“比喻成 蛋糕模型 本身是不能吃 用此模型做出来的 蛋糕(对象)可以吃 。对象比喻成蛋糕。 其中有一个类比较特殊 Object类 在java 当中Object类是王者一般的存在 他是所有类的父类 。在javascript 当中 他的特殊在于没有任何属性和方法 所以由他创造出 对象 并对此对象随意添加属性及方法。
说起面向对象,其中有一个比较重要的知识点就是”工厂模型“
工厂模型大致分三步
原料
加工
出厂
看一个小例子
var object = new Object();
object.name = 'zhangsan ';
object.age = " 21";
object.showName = function(){
alert('我的名字: '+this.name);
};
object.showAge = function(){
alert('我的年龄:'+this.age);
};
object.showName();
object.showAge();
var object2 = new Object();
object2.name = 'lisi ';
object2.age = " 24";
object2.showName = function(){
alert('我的名字: '+this.name);
};
object2.showAge = function(){
alert('我的年龄:'+this.age);
};
object2.showName();
object2.showAge();
输出是弹出 两个人各自的名字和年龄 。但是考虑到如果有100个人 ,就需要重复写100此上面的代码 为了简化代码 减少代码冗余。可以写成如下函数:
function createPerson(name,age){
var object = new Object();
object.name = name;
object.age = age;
object.showName= function(){
alert('我的名字:'+this.name);
}
object.showAge=function(){
alert('我的年龄:'+this.age);
}
return object;
}
var persion1 = createPersion('zhangshan','22');
person1.showName();
person2.showAge();
var persion2 = createPersion('lisi','23');
persion2.showName();
persion2.showAge();
此时的代码就已经简化了许多,虽然很简单的一段代码 ,但是它有一个很高大上的名称:构造函数 其实就是一个普通的函数 ,他的功能是构造出一个对象,然后对此对象完善一些属性及功能。因为人们常用到此函数,所以为此函数起了一个名字 叫构造函数。
仔细分析此构造函数 先产生对象object(原料), 然后为此对象赋予一些属性及方法 (加工),最后 返回此对象return(出厂)。整个一系列流程 称之为 工厂模式
有两个问题 :
第一个关键字new:
如果在方法前面加一个new 代表什么意思呢? (在所有的方法前面都可以加new)
看如下代码
function aa(){
alert(this);
}
aa();
new aa();
此时输出的结果为 第一个window对象 第二个 object 对象
这表明如果在方法前 加上new 系统会偷偷创建一个空白对象 并将此对象返回
那么 之前的工厂模式就可以写成:
function createPerson(name,age){
//var object = new Object();
this.name = name;
this.age = age;
this.showName= function(){
alert('我的名字:'+this.name);
}
this .showAge=function(){
alert('我的年龄:'+this.age);
}
//return object;
}
var persion1 = new createPersion('zhangshan','22');
var persion2 = new createPersion('lisi','23');
persion.showName();
persion.showAge();
如果没有new 那么函数会重复 资源会浪费 所以在此加上一个new
但是上述的代码还有一个问题就是两个persion都是调用的同一种方法(但是不相同的方法 persion1.showName !=persion2.showName),为了将其简化,
这时就用到了 原型(prototype)的概念
原型在我看来 更像是 css当中的 .classname ,修改他可以影响一类元素;在已有对象中加入自己的属性,方法 ; 原型修改对已有对象的影响。
var arr1 = new Array(12,565,5,6,78,78);
var arr2 = new Array(3748,732874,4894,494);
arr1.sum= function(){
var result = 0
for(var i = 0;i<this.length;i++){
result+=this[i]
}
return result ;
}
alert(arr1.sum());
上述代码当中 给arr1 代码添加一个 sum 事件,相当于在标签内添加一个行内样式,只作用在当前标签(arr1)一样 arr2.sum()是undefined 此时如果想要arr2也有sum事件 的话可以写成
var arr1 = new Array(12,565,5,6,78,78);
var arr2 = new Array(3748,732874,4894,494);
Array.prototype.sum= function(){
var result = 0
for(var i = 0;i<this.length;i++){
result+=this[i]
}
return result ;
}
alert(arr1.sum());
alert(arr2.sum());
此时除了 arr1 以外 arr2 也有了sum 事件。
那么之前的工厂模式 利用原型就可以改写成:
function createPerson(name,age){
//var object = new Object();
this.name = name;
this.age = age;
//return object;
}
CreatePersion.prototype.showName= function(){
alert('我的名字:'+this.name);
}
CreatePersion.prototype.showAge=function(){
alert('我的年龄:'+this.age);
}
var persion1 = new CreatePersion('zhangshan','22');
var persion2 = new CreatePersion('lisi','23');
上面在自己定义的类createPersion中利用原型添加方法 showAge 和showName 则 任何一个new 了createPersion 的对象都有这两个方法 。那么此时的 persion1.showName ()=persion2.showName()
他两个对象其实调用的 同一种方法
在上述的例子当中我们将
用构造函数 添加属性; 因为属性是各种各样的;
用原型 添加方法; 但是方法都是一样的方法;
此模式就是 混合方式:
混合的构造函数/原型 方式
Mix Constructor Function/Prototype Method
需要注意的是 类名的首字母大写。
用混合方式构造对象是面向对象的当中常见的编程方式。
the end。