js面向对象设计之class类
class 相对 function 是后出来的,既然 class 出来了,显然是为了解决 function 在处理面向对象设计中的缺陷而来。
下面通过对比,来看看 class 作为 ES6 中的重大升级之一的优势在哪里:
为了更好的对比,请参见我的另外一篇博文: js面向对象设计之 function 类。 1、class 写法更加简洁、含义更加明确、代码结构更加清晰。
2、class 尽管也是函数,却无法直接调用(不存在防御性代码了)。
3、class 不存在变量提升。
4、class 为污染 window 等全局变量(这点很赞啊)。
5、class 函数体中的代码始终以严格模式执行(新手写的代码可靠性也必须上来了) /* ReferenceError: Class01 is not defined */
try { var ins01 = new Class01(); } catch ( e ) { console.error( e ); }
class Class01 { }
console.log( typeof Class01 ); /* function */
/* Class constructor Class01 cannot be invoked without 'new' */
try { Class01() } catch ( e ) { console.error( e ); }
console.log( window.Class01 ); /* undefined */
6、可直接使用 set 和 get 函数。这比 function 要好用多了。
据我所知,vue 中的数据绑定是通过 set 和 get 来实现,而这里 class 可以使用便捷的如同普通的函数的写法。
function 中则需要通过 Object.defineProperty 的方式来设置 set 和 get,繁琐且代码可读性差。 class Class01{
constructor() { }
get name(){
console.log( 'getter' );
return this._name;
}
set name( v ){
this._name = v;
console.log( 'setter' );
return this;
}
}
var ins01 = new Class01();
ins01.name; /* getter */
ins01.name = ; /* setter */
7、class 内部方法中若涉及到 this,则一定要注意。class 中的 this 永远都不会指向 window。
熟悉 function 的应该知道,function 类的实例方法,可能指向 window(在某些情况下,具体读者可自行百度,也可阅读下述例子推敲)。
而 class 则在 this 可能指向 window 的情况下,将 this 指向 undefined。如下:
class Class01 {
constructor() {
this.a = 'a';
}
geta(){
return this.a;
}
}
let ins01 = new Class01();
console.log( ins01.geta() ); /* a */
let obj = {};
obj.a = 'objA';
obj.geta = ins01.geta;
console.log( obj.geta() ); /* 'objA' */
window.a = 'windowA';
window.geta = ins01.geta;
/* Cannot read property 'a' of undefined */
/* 若是 function 类此处会返回 'windowA' */
try { geta() } catch ( e ) { console.error( e ); }
8、class 可以从 javascript 中著名的几大类中进行继承:Array、number、string....,显然 function 是做不到的。
下面给一个简单的示例:
class Class01 extends Array { }
let ins01 = new Class01( , , 3 ); /* [1,2,3] */
let arr = ins01.shift(); /* [2,3] */
arr instanceof Class01; /* false */
ins01 instanceof Class01; /* true */ 小tips:在 mozilla 的开发者指南中看到一种比较高端的东西(关于从原生类继承肯定还有话题,会继续学习):
static get [Symbol.species]() { return Array; }
参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes 9、class 中有一个对象(姑且这么称呼,关于 super 显然还必须要有话题)super,这个对象可以取到父类的方法、构造函数等。
这显然是 function 无法比拟的。在 class 的构造函数中,必须调用 super(),否则该子类就毫无用处。当然静态方法还是可以用用。
下面有一个例子,可以重写父类的方法,扩充父类方法的职责(注意是扩充而不是重写,当然也可以选择重写)。
这一点相当的赞啊,有时候我们并不需要改写父类的某个方法,我们可能会因为项目的需求而扩充父类接口的功能。
class Class01 {
    constructor( name ){
        this.name = name;
    }
    geta(){
        console.log( this.name + ' 父类方法.' );
    }
}
class Class02 extends Class01 {
    geta(){
        super.geta();
        console.log( this.name + ' 子类方法.' );
    }
}
var l = new Class02( 'Class02' );
l.geta();
10、class 中不存在实例方法,class 中定义所有方法都是原型方法。这些方法也都是不可枚举的,使用 for in 这种方式无法遍历到它们。
11、class 不能使用 return 来返回一个实例(等等,我还没有试验过,不好意思,我会马上试验一下)。
  20180101编辑验证,class 的 constructor 可以使用 return,因此 class 与 function 一样可以返回任意的内容。
若不写 return 语句,或返回是数值、字符串等非引用类型的值,则 constructor 任然会返回 this(实例)。return [] 或 return {} 都会使得 new 关键字并不会返回 class 的实例
说了这么多的不同点,再来说说 class 和 function 的相同之处:
1、静态方法  在这点上,两者还是有相似之处的。
尽管相似,显然 class 要更加优雅,可读性也更强,class 使用 static 关键词指定静态方法。
并且class 可以在函数体内定义静态函数,而 function 不能,这无疑也让 function 写出来的代码更加的复杂。
class Class01{
    static geta(){
        console.log( '01的静态方法' );
    }
}
function Class02 () { }
Class02.geta = function () { console.log( '02的静态方法' ); }
Class01.geta();
Class02.geta();
2、私有属性和方法
两者都必须采用闭包的方式才能实现。下面给出 class 的私有属性和方法。
var Class02 = ( function () {
    let pVal ;
    function sayHello(){
        console.log( this ); /* this 指向 window */
        console.log( '欢迎访问nDos的博客' );
    }
    return class Class01{
        constructor( v = '初始值' ){
            pVal = v;
        }
        get val(){
            sayHello();
            return pVal;
        }
        set val( v ){
            pVal = v;
        }
    };
} )();
let ins01 = new Class02();
console.log( ins01.val );
ins01.val = 'hello';
console.log( ins01.val );
ins01 instanceof Class02; /* true */
ins01.constructor.name; /* "Class01" */
小tips:上面的代码显示 ins01 是 Class02 的实例,但 ins01 的构造函数 name 属性却是 Class01。
显然这在项目中不可行,会给类的使用者造成困惑。下例可解决这个问题:
var Class01 = ( function () {
    return class Class01 { };
} )();
let ins01 = new Class01();
ins01 instanceof Class01; /* true */
ins01.constructor.name; /* "Class01" */
3、class 和 function 都有初始化的过程,也就是给实例 this 进行包装处理的过程。二者尽管这个过程都存在,但还是有些区别,
class 只能在 constructor 中初始化,如果涉及继承,还必须调用 super();function 的整个函数体都在执行初始化。
总结:
1、class 作为前端的面向对象设计之关键词,使得前端大型项目的开发变得容易:类的管理更加清晰,功能更加强大。
2、显然与 class 关键字一起出现的关键字 extends 是配套的。使得继承关系更加清晰。
      继承再也不用写一堆的prototype指着这个指着那个,项目代码结构更加明确。
3、当然,关于 class 该博文并未挖的很深,留待下文。
												
											js面向对象设计之class类的更多相关文章
- js面向对象设计之function类
		
本文仅探讨如何合理的使用 function 在 javascript中实现一个面向对象设计的类.总所周知,javascript 并不能实现一个真正意义上的类,比如 protect 比如 函数重载.下面 ...
 - js面向对象设计之class继承
		
EcmaScript 2015 (又称ES6)通过一些新的关键字,使类成为了JS中一个新的一等公民.但是目前为止,这些关于类的新关键字仅仅是建立在旧的原型系统上的语法糖,所以它们并没有带来任何的新特性 ...
 - JS面向对象设计-理解对象
		
不同于其他面向对象语言(OO,Object-Oriented),JS的ECMAScript没有类的概念, 它把对象定义为"无序属性(基本值.对象.函数)的集合",类似于散列表. 每 ...
 - js面向对象设计之class中一些坑和技巧
		
this的指向 super 类工厂,类中定义方法名时,可以使用字符串,这就可以创建工厂函数(类似模板类) Generator 函数 静态属性和私有属性.私有方法 new.target
 - JS面向对象设计-创建对象
		
Object构造函数和对象字面量都可以用来创建单个对象,但是在创建多个对象时,会产生大量重复代码. 1.工厂模式 工厂模式抽象了创建具体对象的过程.由于ECMAScript无法创建类,我们用函数来封装 ...
 - 【JavaScript】 JS面向对象的模式与实践  (重点整治原型这个熊孩子 (/= _ =)/~┴┴   )
		
参考书籍 <JavaScript高级语言程序设计>—— Nicholas C.Zakas <你不知道的JavaScript> —— KYLE SIMPSON 在JS的面向 ...
 - js面向对象编程  ----  系列教程
		
原 js面向对象编程:数据的缓存 原 js面向对象编程:如何检测对象类型 原 js面向对象编程:if中可以使用那些作为判断条件呢? 原 js面向对象编程:this到底代表什么?第二篇 原 js面向对象 ...
 - python之面向对象设计、编程
		
面向对象 一.编程三个范式 1.面向过程编程 2.函数式编程 数学层面的函数 python中的函数编程 3.面向对象编程 二.面向对象设计 1.类:把一类事物共同的特征和共同的动作整合在一起就是类: ...
 - UML类图与面向对象设计原则
		
1. 引言 从大一开始学习编程,到如今也已经有两年了.从最初学习的Html,Js,JaveSe,再到JavaEE,Android,自己也能写一些玩具.学习过程中也无意识的了解了一些所谓的设计模 ...
 
随机推荐
- 【BZOJ2082】【POI2010】Divine divisor 假的pollard-rho
			
题目大意:给你$m$个数$a_i$,定义$n=\Pi_{i=1}^{m}a_i$.将$n$分解质因数为$\Pi p_i^{k_i} $,$p_i$是质数.请输出$2^{max(k_i)}-1$,以及存 ...
 - 给button添加UAC的小盾牌图标
			
Sample Code: public partial class Form1 : Form { public Form1() { InitializeComponent(); } private v ...
 - Hadoop简介与伪分布式搭建—DAY01
			
一. Hadoop的一些相关概念及思想 1.hadoop的核心组成: (1)hdfs分布式文件系统 (2)mapreduce 分布式批处理运算框架 (3)yarn 分布式资源调度系统 2.hadoo ...
 - Css权重解析
			
Css权重解析 关于CSS权重,我们需要一套计算公式来去计算,这个就是 CSS Specificity,我们称为CSS 特性或称非凡性,它是一个衡量CSS值优先级的一个标准 具体规范入如下: spec ...
 - LogCat里的错误提示 FATAL EXCEPTION: main
			
程序一运行闪退. 原因为包冲突,将冲突的包删除即可.
 - Maven 学习笔记(三)
			
Maven生命周期 在上次我们使用maven package 对项目进行打包.这里就是为其指定一个生命周期.生命周期是包含在一个项目构建中的一系列有序的阶段.Maven有许多不同的生命周期,比如验证( ...
 - elasticsearch基本操作之--使用java操作elasticsearch
			
/** * 系统环境: vm12 下的centos 7.2 * 当前安装版本: elasticsearch-2.4.0.tar.gz */ es 查询共有4种查询类型 QUERY_AND_FETCH: ...
 - struct in_addr 结构体
			
struct in_addr 结构体: struct in_addr { in_addr_t s_addr; }; 表示一个32位的IPv4地址. in_addr_t一般为32位的unsigned i ...
 - CentOS SVN Failed to load JavaHL Library
			
在CentOS 6上的eclipse安装了svbclipse插件后,svn不能使用,并且第一次使用的时候还出现下面错误窗口提示 Failed to load JavaHL Library. These ...
 - DelegatingFilterProxy类的作用
			
使用过springSecurity的朋友都知道,首先需要在web.xml进行以下配置 <filter> <filter-name>springSecurityFilterCha ...