JS面向(基于)对象编程--三大特征
抽象
在讲解面向对象编程的三大特征前,我们先了解什么叫抽象,在定义一个类时候,实际上就是把一类事物的共有的属性和行为提取出来,形成一个物理模型(模板)。这种研究问题的方法称为抽象。
封装
什么是封装?
封装就是把抽象出来的属性和对属性的操作封装在一起,属性被保护在内部,程序的其它部分只有通过授权的操作(函数),才能对属性进行操作。
封装--访问控制修饰符
电视机的开关,对音量,颜色,频道的控制是公开的,谁都可以操作,但是对机箱后盖,主机板的操作却不是公开的,一般由专业维修人员来玩。那么在js中如何实现这种类似的控制呢?请看下例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function Person(name, agei, sal) {
this.name = name;//公开属性
var age = agei;//私有属性
var salary = sal;//私有属性
//在类中如何定义公开方法(特权方法),私有方法(内部方法)
//如果我们希望操作私有的属性,则可用公开方法实现
this.show = function() {
window.alert(age+" "+salary);
}
//私有方法,可以访问对象的属性
function show2() {
window.alert(age+" "+salary);
}
}
var p1 = new Person("sp", 20, 50000);
window.alert(p1.name);
p1.show();
p1.show2();//Uncaught TypeError: p1.show2 is not a function
</script>
</head>
<body> </body>
</html>
js提供有以下几种控制方法和属性的访问权限:
- 公开级别:对外公开
- 私有级别:类本身可以访问,不对外公开
通过prototype给所有对象添加方法,但是这种方法不能访问私有变量和私有方法。
例,
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function Person() {
this.name = "abc";
var age = 90; this.abc = function() {
window.alert("abc()");
} function abc2() {
window.alert("abc2()");
}
} Person.prototype.fun1 = function() {
window.alert(this.name);// ok
//window.alert(age);// no ok Uncaught ReferenceError: age is not defined
//window.alert(this.age);// 输出undefined
this.abc();// 注意:不要漏掉this
//abc2();// no ok
}
var p1 = new Person();
p1.fun1(); fun1();// Uncaught ReferenceError: fun1 is not defined
</script>
</head>
<body> </body>
</html>
特别注意:类名.prototype.函数名=function(){}这个也称为后置绑定。
继承
1、为什么需要继承?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function MidStu(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
//计算学费
this.payFee = function(money) {
window.alert("应交"+money*0.8);
}
}
function Pupil(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
//计算学费
this.payFee = function(money) {
window.alert("应交"+money*0.5);
}
}
</script>
</head>
<body> </body>
</html>
问题:以上示例代码冗余。
解决方案:抽象出一个学生类,即把中学生和小学生的共性取出。如下例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
//怎么解决代码冗余-->继承
//抽象出一个学生类,即把中学生和小学生的共性取出
function Stu(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
}
function MidStu(name, age) {
/*
window.alert(Stu);
this.stu = Stu;这一句其实相当于下面这句
this.stu = function Stu(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
};
*/
this.stu = Stu;
this.stu(name, age);//JS中实际上是通过对象冒充,来实现继承,这句话不能少,因为js是动态语言(执行的时候才分配空间),如果不执行它则不能实现继承 //MidStu可以覆盖Stu父类的show
/*
this.show = function() {
window.alert("MidStu show();");
}
*/
}
function Pupil(name, age) {
this.stu = Stu;
this.stu(name, age);
}
var midStu = new MidStu("阿昀", 20);
//window.alert(midStu.name);// undefined
//midStu.show();//Uncaught TypeError: midStu.show is not a function
midStu.show();
</script>
</head>
<body> </body>
</html>
继承--解决之道:
继承可以解决代码利用,让我们的编程更加靠近人类思维,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类(比如刚才的Stu),在父类中定义这些相同的属性和方法,所有的继承类不需要重新定义这些属性和方法,js中没有extends关键字,它可以通过如下方式实现继承。
- 对象冒充
- call及apply
继承--小结:
- js可以实现多重继承
- Object类是js所有类的基类
方法重载(overloading)及覆盖(overriding)
简单的说:方法重载就是类的同一种功能的实现方式,到底采用哪种方式,取决于调用者给出的参数。
js不支持重载操作(即不可以通过参数的个数来决定调用哪个函数,但是因为js本身支持可变参数,所以,它可以看成天然支持重载)。如下例:
function abc() {
if(argument.length = ...) {// 通过参数个数来判断执行哪个代码
} else if(...) {
} ....
}
因为javascript中的方法本身就是一个带可变参数的,通过在方法体内检测方法的参数情况,来实现重载的效果。[调用最后那个方法]
覆盖,也称为改写,就是指子类中定义的方法替换掉父类的方法。(案例说明)
多态
所谓多态,就是指一个引用(类型)在不同情况下的多种状态,在java中多态是指通过指向父类的引用,来调用在不同子类中实现的方法。
js实际上是无态的,是一种动态语言,一个变量的类型是在运行的过程中由js引擎来决定的,所以说js天生就支持多态。
一个多态的经典案例:

代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function Master() {
//给动物喂食
this.feed = function(animal, food) {
window.alert(animal.constructor);
document.writeln("主人给"+animal.name+"喂"+food.name);
}
}
//写一个食物类
function Food(name) {
this.name = name;
//...
}
function Fish(name) {
this.food = Food;
this.food(name);
}
function Bone(name) {
this.food = Food;
this.food(name);
}
function TaoZi(name) {
this.food = Food;
this.food(name);
}
//动物
function Animal(name) {
this.name = name;
//....
}
function Cat(name) {
this.animal = Animal;
this.animal(name);
}
function Dog(name) {
this.animal = Animal;
this.animal(name);
}
function Monkey(name) {
this.animal = Animal;
this.animal(name);
} var cat = new Cat("小猫咪");
var dog = new Dog("小狗");
var fish = new Fish("小鱼");
var bone = new Bone("骨头"); var master = new Master();
master.feed(cat, fish);
master.feed(dog, bone);
master.feed(new Monkey("小猴"), new TaoZi("水蜜桃"));
</script>
</head>
<body> </body>
</html>
闭包
老韩讲闭包时到底有多随意啊!我相信讲闭包,又得开一个系列了。所以这里仅作初步了解。
闭包的解释:
- 闭包和垃圾回收机制GC是相关联的
- 闭包实际上是在涉及到一个对象的成员属性,何时被GC处理的问题
- 怎样才能对对象的属性形成一个闭包
如下例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
/*闭包(closure)——讨论的(回收时机问题)是什么时候回收什么时候不回收*/
function A() {
var i = 0;
function b() {
window.alert(i++);
}
return b;
}
//闭包<--->GC
A();//此时内存中会有一个i的存储空间,被GC处理(是不是立马呢?至少会被当作垃圾,GC会认为被处理了)
var c = A();//这种用法,GC不会把i当作垃圾
// c();
window.alert("aa");
//...
//...
c();//输出0
c();//输出1,从而证明i变量被闭包
</script>
</head>
<body> </body>
</html>
JS面向(基于)对象编程--三大特征的更多相关文章
- js面向(基于)对象编程—类(原型对象)与对象
JS分三个部分: 1. ECMAScript标准--基础语法 2. DOM Document Object Model 文档对象模型 3. BOM Browser Object Moldel 浏览 ...
- JS面向(基于)对象编程--构造方法(函数)
构造函数(方法)介绍 什么是构造函数呢?在回答这个问题之前,我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就直接 ...
- JavaScript学习总结(九)——Javascript面向(基于)对象编程
一.澄清概念 1.JS中"基于对象=面向对象" 2.JS中没有类(Class),但是它取了一个新的名字叫“原型对象”,因此"类=原型对象" 二.类(原型对象)和 ...
- JavaScript学习总结(5)——Javascript面向(基于)对象编程
一.澄清概念 1.JS中"基于对象=面向对象" 2.JS中没有类(Class),但是它取了一个新的名字叫"原型对象",因此"类=原型对象" ...
- js面向(基于)对象编程-三大特征
①抽象 js提供以下几种控制方法和属性的访问权限: (1)公开级别:对外公开 (2)私有级别:类本身可以访问,不对外公开 案例如下所示: function Person(name,age,sal){ ...
- JavaScript基于对象编程
js面向对象特征介绍 javascript是一种面向(基于)对象的动态脚本语言,是一种基于对象(Object)和事件驱动(EventDirven)并具有安全性能的脚本语言.它具有面向对象语言所特有的各 ...
- python---面对对象的三大特征
一.三大特征 面对对象的三大特征:继承.多态和封装,继承在面向对象类的创建中非常常见. 1.继承 为什么会有继承,当我们要创建一个新类的时候,发现他有很多属性或者反法都和我们另一个类的方法相同,这时我 ...
- 《Essential C++》读书笔记 之 基于对象编程风格
<Essential C++>读书笔记 之 基于对象编程风格 2014-07-13 4.1 如何实现一个class 4.2 什么是Constructors(构造函数)和Destructor ...
- Python学习day24-面向对象的三大特征之继承
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
随机推荐
- centos6.4 安装 hive 0.12.0
环境:centos6.4 64bit, 前提:hadoop已经正常运行,可以使用hadoop dfsadmin -report查看 hive 解压 tar zcvf hive-0.12.0.ta ...
- 关于Swift中实现Lazy initialize的方式
在oc中我们通过 -(CardMatchingGame *)game { if(!_game) _game=[[CardMatchingGame alloc] initWithCardCount:[s ...
- 67.ARP协议
ARP是地址解析协议Address Resolution Protocol的缩写.是一个位于TCP/IP协议栈中的低层协议,负责将某个IP地址解析程对应的MAC地址.在局域网中,网络实际传输的是“帧” ...
- “psp”软件需求规约
1 系统概述 1.1 概述 该产品是基于软件开发的个人软件过程(personal software process)系统.基本信息有软件开发人员,项目经理,研发经理和管理层登录系统后根据各自的相应权限 ...
- C++ STL中Map的按Key排序和按Value排序
map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...
- nodejs笔记一--模块,全局process对象;
一.os模块可提供操作系统的一些基本信息,它的一些常用方法如下: var os = require("os"); var result = os.platform(); //查看操 ...
- Could not load file or assembly 'Microsoft.Office.Interop.Word, Version=14.0
参考地址一:点击这里 参考地址二:点击这里 解决方法: 使用office COM元件,电脑里必须要有相对应的版本,比如 Excel 14.0是对应Excel 2010 Excel 12.0是对应Exc ...
- 修改Input中Placeholder默认提示颜色(兼容)
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder { color: #f00; } input:-moz-pl ...
- MySQL - 定时备份
创建备份目录,在这里以/root/bak/mysql为例: cd mkdir bak cd bak mkdir mysql 在/usr/sbin下touch一个sh: cd /usr/sbin tou ...
- android activity之间传递返回值
activity A,跳转至 Activity B ,A传参数user_name给B,然后B再返回修改后的参数user_name给A 首先A传user_name给B Intent input_B = ...