js中OOP小指南
js中OOP小指南
在指南中,我将尝试解析以面向对象规范聚焦的es6的新特性。
首先,
什么是设计模式
范例是某个事务的例子或模型,在某种情况下,按照一种模式创建了计算机程序。
什么是面向对象
显然你意识到这是一种设计模式,像已经存在的这个模式,我们还有许多其它的设计模式,比如函数式编程和反应式编程。
这种模式的特点
我们在这个模式中所做的是以更接近实际的方式编程,我们使用类,对象,方法,属性等进行编程,并且集成了抽象,封装,模块化,隐私,多态和继承等术语。
javascript的问题是,它不是一个很规范的语言,为什么?因为javascript所有的都是对象,因此我们可以使用很著名的
prototype来解决这个问题。
在ES5中,我们使用下面的例子实现工程模式:
console.log('*** PERSON ***');
function Person (name) {
this.name = name;
}
// 明确属性和方法
Person.prototype = {
eyes: 2,
mouth: 1,
sleep: function () {
return 'zzz';
}
};
// 创建一个叫Nick的人
const p1 = new Person('Nick');
console.log(
`name: ${p1.name}`,
`eyes: ${p1.eyes}`,
`mouth: ${p1.mouth}`,
p1.sleep()
);
console.log('*** EMPLOYEE ***')
// 如果我们有class属性,我们可以继承person的属性
function Employee (name, salary) {
this.name = name;
this.salary = salary;
}
// Prototype 继承
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee; // Set his own constructor
// 现在可以做相同的事情了
// 创建一个employee
const em1 = new Employee('John', 3000);
console.log(
`name: ${em1.name}`,
`salary: ${em1.salary} USD`,
`eyes: ${em1.eyes}`,
`mouth: ${em1.mouth}`,
em1.sleep()
);
现在使用ES6,用一种简单的方式实现上面的操作,但是一定记住这仅仅是语法糖:
class Person {
constructor (name) {
this.name = name;
this.eyes = 2;
this.mouth = 1;
}
sleep () {
return 'zzz';
}
}
class Employee extends Person {
constructor (name, salary) {
super(name);
this.salary = salary;
}
}
const p1 = new Person('Nick');
console.log(
`name: ${p1.name}`,
`eyes: ${p1.eyes}`,
`mouth: ${p1.mouth}`,
p1.sleep()
);
const em1 = new Employee('John', 3000);
console.log(
`name: ${em1.name}`,
`salary: ${em1.salary} USD`,
`eyes: ${em1.eyes}`,
`mouth: ${em1.mouth}`,
em1.sleep()
);
在这种情况下,通过extends关键字我们只需说:好吧,我想要继承Person类的属性。但在背后,这与我们在使用es5示例中的原型所做的相同。
静态方法
class Dog {
static whatIs() {
return 'A dog is a beatiful animal';
}
}
// 因此,我们通过静态方法,不用实例化一个新的对象就可以访问方法
console.log( Dog.whatIs() );
私有属性
javascript并不像java和C#那样拥有私有属性。重要的是,在JavaScript中我们有一个用于“私有”值的约定,该约定是在该单词之前使用下划线:
class Person {
constructor (name, phone) {
this.name = name;
this._phone = phone;
}
}
const p1 = new Person('John', 544342212);
// 实际上 'phone' 不是一个私有属性,因为我们可以这样使用:
console.log(p1._phone);
不过在ES6中,我们有一个叫WeakMap的对象,它允许我们创建私有属性。让我们来看下:
// 因为它是保留字,所以不要使用private作为变量名称
const secret = new WeakMap();
class Person {
constructor (name, phone) {
this.name = name;
secret.set(this, {_phonenumber: phone});
}
}
const p1 = new Person('John', 544342212);
// 现在_phonenumber是一个私有属性
console.log(p1. _phonenumber); // Print's undefined
Getters 和 Setters
当我们拥有私有方法时通常会创建一个返回私有值的公共方法,因此我们必须返回一个值,并定义一个新的值。
const secret = new WeakMap();
class Person {
constructor (name, phone) {
this.name = name;
secret.set(this, {_phonenumber: phone
}
get phoneNumber() {
return secret.get(this)._phonenumber;
}
set phoneNumber(newNumber) {
secret.get(this)._phonenumber = newNumber;
}
}
const p1 = new Person('John', 544342212);
const p2 = new Person('Tom', 111111);
// 通过getter获取手机号
console.log(p1.phoneNumber); // Print's the number
// 设置新的手机号
p1.phoneNumber = 432232323;
p1.phoneNumber = 222222;
console.log(p1.phoneNumber, p2.phoneNumber); // 获得新的手机号
多态
在执行过程中,一个对象引用它的类的事件或者任何子类的事件。子类可能会重新定义一种方法。
class Person {
constructor(name) {
this.name = name;
}
me() {
return `My name is ${this.name}`;
}
}
const axel = new Person('Axel');
console.log(axel.me());
// -> 'My name is Axel'
class Employee extends Person {
constructor (name, salary) {
super(name);
this.salary = salary;
}
me() {
return `My name is ${this.name} and my salary is ${this.salary}`;
}
}
const nick = new Employee('Nick', 3000);
console.log(nick.me());
// -> 'My name is Nick and my salary is 3000'
一些概念
- class:创建新的类或者模型。
- constructor: 实例化类时初始化对象的方法。
- extends: 用于设置继承
- super: 设置调用父亲的继承属性的方法。supe必须位于构造函数的第一行。
- get: 获取某个值的方法。
- set: 重新定义某个值的方法。
js中OOP小指南的更多相关文章
- JS中OOP之模拟封装和继承和this指向详解
大家好,今天我带大家学习一下js的OOP, 大家都知道,面向对象有三个基本特征,继承,封装和多态,面向对象的语言有那么几种,C++,PHP,JAVA等,而功能强大的JS可以模拟实现面向对象的两大特征, ...
- (网页)JS中的小技巧,但十分的实用!
转自CSDN: 1.document.write(”"); 输出语句2.JS中的注释为//3.传统的HTML文档顺序是:document->html->(head,body)4. ...
- 总结下常用js中的小语法和技巧
1,数组对象遍历 对一个级数对象进行遍历,取出每个值 var arr={ "result":[ {"time":"2018-10-24 12:12:1 ...
- 学习JS中的小问题
1.如果载入的2个js文件中有重名函数,那么调用的时候怎么分别调? 第二个文件载入无效. 2.checkbox jQuery对象的checked属性在选中时为checked,否则为undefined: ...
- js中一些小知识点总结--持续更新
以下知识点来自于编写高质量代码-改善JavaScript程序的188个建议,只用于自我知识的补充. 一.NaN 1.NaN是一个特殊的数量值,不表示一个数字,尽管下面的代码仍然是返回类型为number ...
- js中的小案例(一)
效果图: html代码: <div id="date"> <p> <span id="prev">上一月</span& ...
- 小结JS中的OOP(下)
关于JS中OOP的具体实现,许多大神级的JS专家都给出了自己的方案. 一:Douglas Crockford 1.1 Douglas Crockford实现的类继承 /** * 原文地址:http:/ ...
- 小结JS中的OOP(中)
此篇文章主要是提炼<JavaScript高级程序设计>中第六章的一些内容. 一:JS中OOP相关的概念 开始之前先总结JS中OOP相关的一些概念: 构造函数:JS中的构造函数就是普通的函数 ...
- JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解
前 言 JRedu 学过程序语言的都知道,我们的程序语言进化是从"面向机器".到"面向过程".再到"面向对象"一步步的发展而来.类似于 ...
随机推荐
- NIO--2-代码
package com.study.nio; import java.io.IOException; import java.net.InetSocketAddress; import java.ni ...
- JQuery插件supersized.js实现背景图片淡入浅出
淡入浅出的网站背景图片切换,其实是引用了JQuery插件supersized,效果很炫吧.其实这个插件功能很强大,可以做很多图片类的效果.这些需要等待我们自己去探索. 下面是这个效果的代码只有一行: ...
- Codeforces Round #383 (Div. 1) C(二分图)
一道很巧妙的二分图的题目 简单分析性质可知,一个合法序列一定是由12,21这样的子串构成的,所以相邻的每隔2个两两配对 然后BF和GF互相配对,思考一下,如果存在奇环,那么必定有一个BG有两个GF,或 ...
- Codeforces Round #390 (Div. 2) E(bitset优化)
题意就是一个给出2个字符矩阵,然后进行匹配,输出每个位置的匹配的结果 (超出的部分循环处理) 一种做法是使用fft,比较难写,所以没有写 这里使用一个暴力的做法,考虑到一共只出现26个字符 所以使用一 ...
- [NOIP2002] 字串变换 宽搜+深度优化
这道题硬是让我用STL水过.......而且题解里说的什么双向宽搜,交替扩展............... 这道题反正,STL用就用吧,但是状态数可以卡到千亿级别,因为这个东西是阶乘扩展的,然后我们发 ...
- 妮可妮可妮 [Hash]
妮可妮可妮 题目描述 小P特别喜欢动画Love Live中的角色妮可,每当他听到妮可说"niconiconi"时,他总会感到特别兴奋,还会露出绅士般的微笑. 作为一名理论计算机科学 ...
- HDU1151:Air Raid(最小边覆盖)
Air Raid Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- 「6月雅礼集训 2017 Day1」看无可看
[题目大意] 给出n个数,a[1]...a[n],称作集合S,求
- [FZU2261]浪里个浪
TonyY是一个喜欢到处浪的男人,他的梦想是带着兰兰姐姐浪遍天朝的各个角落,不过在此之前,他需要做好规划. 现在他的手上有一份天朝地图,上面有n个城市,m条交通路径,每条交通路径都是单行道.他已经预先 ...
- TCP/IP Http的区别
TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据. 关于TCP/IP和HTTP协议的关系,网络有一段比较容易理解的介绍:“我们在传输数据时,可以 ...