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类的更多相关文章

  1. js面向对象设计之function类

    本文仅探讨如何合理的使用 function 在 javascript中实现一个面向对象设计的类.总所周知,javascript 并不能实现一个真正意义上的类,比如 protect 比如 函数重载.下面 ...

  2. js面向对象设计之class继承

    EcmaScript 2015 (又称ES6)通过一些新的关键字,使类成为了JS中一个新的一等公民.但是目前为止,这些关于类的新关键字仅仅是建立在旧的原型系统上的语法糖,所以它们并没有带来任何的新特性 ...

  3. JS面向对象设计-理解对象

    不同于其他面向对象语言(OO,Object-Oriented),JS的ECMAScript没有类的概念, 它把对象定义为"无序属性(基本值.对象.函数)的集合",类似于散列表. 每 ...

  4. js面向对象设计之class中一些坑和技巧

    this的指向 super 类工厂,类中定义方法名时,可以使用字符串,这就可以创建工厂函数(类似模板类) Generator 函数 静态属性和私有属性.私有方法 new.target

  5. JS面向对象设计-创建对象

    Object构造函数和对象字面量都可以用来创建单个对象,但是在创建多个对象时,会产生大量重复代码. 1.工厂模式 工厂模式抽象了创建具体对象的过程.由于ECMAScript无法创建类,我们用函数来封装 ...

  6. 【JavaScript】 JS面向对象的模式与实践 (重点整治原型这个熊孩子 (/= _ =)/~┴┴ )

    参考书籍 <JavaScript高级语言程序设计>—— Nicholas C.Zakas <你不知道的JavaScript>  —— KYLE SIMPSON   在JS的面向 ...

  7. js面向对象编程 ---- 系列教程

    原 js面向对象编程:数据的缓存 原 js面向对象编程:如何检测对象类型 原 js面向对象编程:if中可以使用那些作为判断条件呢? 原 js面向对象编程:this到底代表什么?第二篇 原 js面向对象 ...

  8. python之面向对象设计、编程

    面向对象 一.编程三个范式 1.面向过程编程 2.函数式编程 数学层面的函数 python中的函数编程 3.面向对象编程 二.面向对象设计 1.类:把一类事物共同的特征和共同的动作整合在一起就是类: ...

  9. UML类图与面向对象设计原则

    1. 引言     从大一开始学习编程,到如今也已经有两年了.从最初学习的Html,Js,JaveSe,再到JavaEE,Android,自己也能写一些玩具.学习过程中也无意识的了解了一些所谓的设计模 ...

随机推荐

  1. android 代码实现back键功能

    方案一,简单但响应慢: doExec("input keyevent 4"); public String doExec(String cmd) { String s = &quo ...

  2. Java堆内存溢出模拟

    先了解一下Java堆: 关于Java内存区域的分配,可以查看Java运行时数据区域一篇文章. Java堆是虚拟机内存管理中最大的一块区域,该区域是线程共享的,某Java进程中所有的线程都可以访问该区域 ...

  3. 【7】JMicro微服务-服务路由,负载均衡

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl   1.关于服务路由和负载均衡 服务路由:根据预先配置好的策略,为客户端选择一个当前可用的服务提供者,根据策略选择一个可用的 ...

  4. OS之内存管理 ---基本的内存管理策略(二)

    分段 基本方法 分段就是基于用户视图的内存管理方案.逻辑地址空间是由一组段构成的,每个段都有名称和长度.地址指定了段名称和段内偏移.因此用户通过两个量来指定地址:段名称和段偏移. 为了简单,进行对段的 ...

  5. POJ 2363

    #include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...

  6. (转)rpm2cpio和cpio

    原文:https://blog.csdn.net/jubincn/article/details/6687550 rpm2cpio命令:将rpm格式的文件转为cpio格式的文件.rpm是linux中常 ...

  7. hbase集群中其中某个regionserver 没有启动

    第一步: date命令查看各个机器的时间 发现linux02机器时间差了2个多小时 第二步:ntpdate pool.ntp.org 修改错误时间的机器 第三步: 重启 hbase

  8. 解析ASP.NET Mvc开发之删除修改数据 分类: ASP.NET 2014-01-04 23:41 3203人阅读 评论(2) 收藏

    目录: 从明源动力到创新工场这一路走来 解析ASP.NET WebForm和Mvc开发的区别 解析ASP.NET 和Mvc开发之查询数据实例 解析ASP.NET Mvc开发之EF延迟加载 ------ ...

  9. 【数组】Remove Duplicates from Sorted Array II

    题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...

  10. Eclipse *版本(图文详解)

    不多说,直接上干货! 关于Eclipse的版本介绍 Eclipse Standard 该版本是eclipse最基础的版本,适合Java se个人开发者.或希望根据自己需求配置插件的开发者使用. Ecl ...