JavaScript 面向对象(一) —— 基础篇
学好JS的面向对象,能很大程度上提高代码的重用率,像jQuery,easyui等,这篇博客主要从细节上一步步讲JS中如何有效地创建对象,也可以看到常见的创建对象的方式,最后也会附上一些JS面向对象的案例。
一、面向对象(Java面向对象亦是如此)
1.对象:对象是一个整体,对外提供一些操作。
2.面向对象:使用对象时,只关注对象提供的功能,不关注其内部细节。比如电脑——有鼠标、键盘,我们只需要知道怎么使用鼠标,敲打键盘即可,不必知道为何点击鼠标可以选中、敲打键盘是如何输入文字以及屏幕是如何显示文字的。总之我们没必要知道其具体工作细节,只需知道如何使用其提供的功能即可,这就是面向对象。
3.JS的对象组成:方法 和 属性
在JS中,有函数、方法、事件处理函数、构造函数,其实这四个都是函数,只是作用不同。函数是独立的存在,方法属于一个对象,事件处理函数用来处理一个事件,构造函数用来构造对象。
首先通过常用的数组来认识下JS的对象:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script> /**
* 定义一个数组
*/
var arr = [1, 2, 3, 4, 5]; /**
* 弹出 object
* 说明数组就是个对象
*/
alert(typeof arr); /**
* 弹出5
* 对象的属性 length
*/
alert(arr.length); /**
* 对象的方法 push
* 弹出 1,2,3,4,5,6
*/
arr.push(6);
alert(arr);
</script>
</head>
<body>
</body>
</html>
4.认识下JS中的this以及全局对象window
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
/**
* 定义一个全局函数
*/
function show(){
alert(this);
}
//调用show()
show(); </script>
</head>
<body>
</body>
</html>

此处的show()函数为一个全局函数,调用show(),alert(this)弹出来的是window对象,说明全局函数属于window。上面定义的show()等于为window添加一个方法,全局的函数和变量都是属于window的,上面的定义等价于下面。
<!DOCTYPE html>
<html>
<head>
<script>
/**
* 为window定义一个show方法
*/
window.show = function(){
alert(this);
}
//调用show()
window.show(); </script>
</head>
</html>
同样的我们也可以根据自己的需求为其它的对象添加方法,比如显示数组:
但是我们不能在系统对象中随意附加方法和属性,否则可能会覆盖已有方法、属性。
<!DOCTYPE html>
<html>
<head>
<script>
var arr = [1,2,3,4,5];
arr.show = function(){
alert(this);
}
arr.show(); //弹出 1,2,3,4,5
</script>
</head>
</html>
从上面的例子也可以看出来,this即表示当前函数的调用者是谁,但是在一种情况下不是的,就是使用new 来创建对象时,this并不是指向调用者的,在后面会有说明。
window是全局对象,可以看下属于window的全局属性和全局方法:


二、JS中自定义对象,逐步分析JS中的创建对象
1.通过Object创建简单对象:
这种方式有一个非常大的弊端,就是如果我有多个人怎么办,每次都要新建一个对象,然后添加属性、方法,这种方式是一次性的,会产生大量重复代码,这是不可取的。
<!DOCTYPE html>
<html>
<meta charset="UTF-8" />
<head>
<script>
/**
* 创建一个新对象
* new Object()创建出来的对象几乎是空白的,需要自己添加属性,方法
*/
var person = new Object();
//为person对象添加属性
person.name = "jiangzhou";
person.age = 22;
//为person对象添加方法
person.showName = function(){
alert("姓名:"+this.name);
}
person.showAge = function(){
alert("年龄:"+this.age);
}
//调用对象的方法
person.showName();
person.showAge(); </script>
</head>
</html>
2.用工厂方式来构造对象:工厂,简单来说就是投入原料、加工、出厂。
通过构造函数来生成对象,将重复的代码提取到一个函数里面,避免像第一种方式写大量重复的代码。这样我们在需要这个对象的时候,就可以简单地创建出来了。
<!DOCTYPE html>
<html>
<meta charset="UTF-8" />
<head>
<script>
//构造函数:工厂
function createPerson(name, age){
var person = new Object(); //原料
person.name = name;
person.age = age; //加工
person.showName = function(){
alert("姓名:"+this.name);
}
person.showAge = function(){
alert("年龄:"+this.age);
}
//出厂
return person;
}
//创建两个对象
var p1 = createPerson("jiangzhou", 22);
var p2 = createPerson("tom", 20); //调用对象方法
p1.showName();
p1.showAge(); p2.showName();
p2.showAge(); </script>
</head>
</html>
但是,这种方式有两个缺点:
①一般我们创建对象是通过new来创建,比如new Date(),这里使用的是方法创建。使用new来创建可以简化一些代码,也带来一些新的特性。
②每个对象都有一套自己的方法,浪费资源(虽然对于现在的计算机来说不算什么,但我们尽量将设计做到最好就行了)。
这里为什么说每个对象都有自己的一套方法呢,是因为创建function()的时候其本质是通过new Function()来创建的,会诞生一个新的函数对象,所以每个对象的方法是不一样的,这样就存在资源浪费的问题了。看第25行代码。
<!DOCTYPE html>
<html>
<meta charset="UTF-8" />
<head>
<script> function createPerson(name, age, sex){
var person = new Object(); person.name = name;
person.age = age;
person.sex = sex; person.showName = function(){
alert("姓名:"+this.name);
}
person.showAge = function(){
alert("年龄:"+this.age);
} /**
* person.showSex = function(){} 等价于 person.showSex = new Function('');
* 也就是说我们在创建这个函数的时候就是新建了一个对象。
*/
person.showSex = new Function('alert("性别:"+this.sex)'); return person;
} //创建两个对象
var p1 = createPerson("jiangzhou", 22, "男");
var p2 = createPerson("Lyli", 20, "女"); alert(p1.showName == p2.showName); //false </script>
</head>
</html>
3.使用new 来创建JS对象
<!DOCTYPE html>
<html>
<meta charset="UTF-8" />
<head>
<script> function Person(name, age){
/**
* 可以假想成系统会创建一个对象
* var this = new Object();
*/ alert(this); //弹出Object this.name = name;
this.age = age; this.showName = function(){
alert("姓名:"+this.name);
}
this.showAge = function(){
alert("年龄:"+this.age);
} /**
* 假想返回了对象
* return this;
*/
} //创建两个对象
var p1 = new Person("jiangzhou", 22);//可以看到在外面new了在function里面就不用new了;在function里面new了,在外面就不用new了;O(∩_∩)O~
var p2 = new Person("Lyli", 20); alert(p1.showName == p2.showName); //false </script>
</head>
</html>
弹出信息显示this即是一个Object(第13行代码)。在方法调用前使用new来创建,function内的this会指向一个新创建的空白对象,而不是指向方法调用者,而且会自动返回该对象。
但是这种方式只解决了第一个问题,每个对象还是有自己的一套方法(第35行代码)。

4.在function原型(prototype)上进行扩展 —— 最终版
原型添加的方法不会有多个副本,不会浪费资源,所有的对象只有一套方法(看第29行代码)。 至于为什么是用的一套方法呢,看第31行代码:因为所有的方法都等于原型上的方法。
<!DOCTYPE html>
<html>
<meta charset="UTF-8" />
<head>
<script> /**
* Person构造函数:在JS中,构造函数其实就可以看成类,对某个对象的抽象定义。
* @param {Object} name
* @param {Object} age
*/
function Person(name, age){
//属性:每个对象的属性各不相同
this.name = name;
this.age = age;
}
//在原型上添加方法,这样创建的所有对象都是用的同一套方法
Person.prototype.showName = function(){
alert("姓名:"+this.name);
}
Person.prototype.showAge = function(){
alert("年龄:"+this.age);
} //创建两个对象
var p1 = new Person("jiangzhou", 22);
var p2 = new Person("Lyli", 20); alert(p1.showName == p2.showName); //true
//这里为什么两个对象的方法是相等的呢,可以看成如下
alert(p1.showName == Person.prototype.showName); //true </script>
</head>
</html>
通过prototype我们还可以很方便的扩展系统对象,按照自己的需求来扩展,而且又能适用于所有地方,又不会浪费资源。如下面对Array进行扩展,求数组和的方法。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<script>
/**
* 对数组原型扩展一个求和的方法;
* 注意不能只加在某个数组对象上,那样的话只能在那个对象上适用。
*/
Array.prototype.sum = function(){
var sum = 0;
for(var i=0;i<this.length;i++){
sum += this[i];
}
return sum;
}
//通过new Array() 和 [] 创建数组完全是一样的效果。
var arr1 = new Array(1,2,3,4,5,6);
var arr2 = [11,22,33,44,55]; alert(arr1.sum());
alert(arr2.sum()); alert(arr1.sum == arr2.sum); //true
alert(arr2.sum == Array.prototype.sum); //true
</script>
</html>
三、案例:JavaScript 面向对象(二) —— 案例篇
JavaScript 面向对象(一) —— 基础篇的更多相关文章
- JavaScript 面向对象(三) —— 高级篇
JavaScript 面向对象(一) —— 基础篇 JavaScript 面向对象(二) —— 案例篇 一.json方式的面向对象 首先要知道,js中出现的东西都能够放到json中.关于json数据格 ...
- JavaScript 面向对象(二) —— 案例篇
看案例前可以先看看基础篇:JavaScript 面向对象(一) —— 基础篇 案例——面向对象的选项卡:把面向过程的程序一步步改成面向对象的形式,使其能够更加的通用(但是通用的东西,一般会比较臃肿). ...
- JS:面向对象(基础篇)
面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念.long long ago,js是没有类的概念(ES6推出了class,但其原理还是基于原型),但是它是基于原 ...
- javascript面向对象系列第一篇——构造函数和原型对象
× 目录 [1]构造函数 [2]原型对象 [3]总结 前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如 ...
- javascript面向对象技术基础总结
javascript面向对象和php不太一样,语法不太相同,总结如下 //cat 对象 function Cat(name,color){ this.name = name;//不确定的成员属性 th ...
- JavaScript进阶【三】JavaScript面向对象的基础知识复习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- javascript之Array基础篇
整理了 Array 中很基础的要掌握的知识点,希望可以帮助初学者,也希望自己以后多用多融会贯通. 创建数组 使用Array构造函数: var a=new Array();//创建一个空数组 var a ...
- javascript面向对象系列第二篇——创建对象的5种模式
× 目录 [1]字面量 [2]工厂模式 [3]构造函数[4]原型模式[5]组合模式 前面的话 如何创建对象,或者说如何更优雅的创建对象,一直是一个津津乐道的话题.本文将从最简单的创建对象的方式入手,逐 ...
- python之路——面向对象(基础篇)
面向对象编程:类,对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 "类" 和 "对象" 来实现,所以,面向对象编程其实就是对 "类&quo ...
随机推荐
- JAVA基础知识之JDBC——JDBC数据库连接池
JDBC数据库连接池 数据库的连接和关闭是很耗费资源的操作,前面介绍的DriverManager方式获取的数据库连接,一个Connection对象就对应了一个物理数据库连接,每次操作都要打开一个连接, ...
- Linux内核分析:打开文件描述符实现
在Linux中每一个进程的数据是存储在一个task_struct结构(定义在sched.h中)中的. struct task_struct { volatile long state; /* -1 u ...
- cmp函数
cmp(x,y),既可以比较数字大小,也可以比较字符串.如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1. 数字的比较 >>> ...
- [转]VB Winsock 控件TCP与UDP连接实例
[-] 可能的用途 选择通讯协议 协议的设置 确定计算机的名称 TCP 连接初步 接受多个连接请求 UDP 初步 关于 Bind 方法 利用 WinSock 控件可以与远程计算机建立连接,并通过用 ...
- word域3
WORD是文字处理软件,我们在日常处理一些文字时经常遇到一些问题,如:各种公式的录入,尽管Word都提供了"公式编辑器",但其插入的却是"对象",有时排版会感觉 ...
- 8.mvc core上传文件
以下方法均是个人,仅供参考 public interface IFileHelper { /// <summary> /// 保存文件 (返回 Test.jpg) 出错就返回 error| ...
- 工厂食堂3D指纹考勤系统解决方案
指纹考勤就餐管理系统利用3D活体指纹技术完成对正式员工就餐管理.就餐者只需办理完入职手续,并登记考勤指纹,就可通过考勤指纹在工厂食堂领餐. 大多数工厂食堂就餐是福利性的,只准员工就餐,不准员工带亲戚朋 ...
- quantile normalization原理
对于芯片或者其它表达数据来说,最常见的莫过于quantile normalization啦. 那么它到底对我们的表达数据做了什么呢?首先要么要清楚一个概念,表达矩阵的每一列都是一个样本,每一行都是一个 ...
- 1. C语言中的数据结构.md
C语言内建数据结构类型 整型 整型数据是最基本的数据类型,不过从整形出发衍生出好几种integer-like数据结构,譬如字符型,短整型,整型,长整型.他们都是最基本的方式来组织的数据结构,一般是几位 ...
- 移动端web开发基础概念
最近在了解移动端web开发的相关知识,有些概念总是模糊不清,这次花费了一些时间整体的梳理了一遍. 分辨率 分辨率可以从显示分辨率与图像分辨率两个方向来分类.显示分辨率(屏幕分辨率)是屏幕图像的精密度, ...