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. margin 和 padding

    一图胜千言!!  参考 CSS padding margin border属性详解

  2. FlexMonkey实战

    文章来源:http://www.cnblogs.com/raol/p/flexmonkey.html 我的有道云笔记:http://note.youdao.com/share/?id=22b79669 ...

  3. 移动端页面模板viewport

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta nam ...

  4. BeautifulSoap库入门

    BeautifulSoup类的基本元素 基本元素 说明 Tag 标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾 Name 标签的名字,<p>-< ...

  5. 【xsy1154】 DNA配对 FFT

    题目大意:给你一个字符串$s$和字符串$w$,字符集为${A,T,C,G}$,你要在字符串$s$中选出一个与$w$长度相同的子串,使得这两个串的差异度最小. 两个字符$c1$,$c2$的差异度为给定的 ...

  6. shiro授权-记调试过程

    根据张开涛老师的shiro教程学习过程中 感觉shiro授权这块有点绕 调试了十几遍 大概有个思路  记录一下 1.单元测试入口 2.subject().isPermitted("+user ...

  7. jQuery过滤选择器:first和:first-child的区别,CSS伪类:first-child

    最近项目中遇到需求:只在第一列不能删除,不显示小叉号:点击可添加一列,后面的列右上角显示小叉号,可以点击删除. 我是使用以下方法解决这个小需求 :CSS伪类选择器:first-child设置所有小叉号 ...

  8. 03——Solr学习之Solr的使用(不会用)

    1.先放上次在linux搭建成功的solr管理UI界面 2.有个很蛋疼的问题我就要吐槽一下了 由于没接触过solr这玩意,在百度上一顿操作搜索怎么用,怎么导入数据,建索引库什么的,看了一大片别人的博客 ...

  9. csc命令

    CSC.exe把Visual C#程序代码编译成IL文件时,有着很多参数和开关选项.正确的了解和运用这些参数和开关有时会解 决一些看似很棘手的问题.下面就通过一张表来大致说明一下这些参数和开关的具体作 ...

  10. 剑指offer三十一之连数中1出现的次数(从1到n整数中1出现的次数

    一.题目 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...