es6学习笔记12--Class
Class基本语法概述JavaScript语言的传统方法是通过构造函数,定义并生成新对象。下面是一个例子。 function Point(x,y){ this.x = x; this.y = y; } Point.prototype.toString = () { return '(' + this.x + ',' + this.y + ')'; }; 上面这种写法跟传统的面向对象语言(比如C++和Java)差异很大,很容易让新学习这门语言的程序员感到困惑。 ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过 //定义类 class Point { constructor(x,y) { x; y; } toString() { ; } } 上面代码定义了一个“类”,可以看到里面有一个 Point类除了构造方法,还定义了一个 构造函数的 class Point { constructor(){ ... } toString(){ } toValue(){ } } 等同于 Point.prototype = { toString(){},toValue(){} }; 在类的实例上面调用方法,其实就是调用原型上的方法。 class B {} let b = new B(); b.constructor === B.prototype.constructor true 类的内部所有定义的方法,都是不可枚举的(non-enumerable)。 constructor方法
class Foo { constructor() { return Object.create(null); } } new Foo() instanceof Foo false 上面代码中, 类的实例对象生成类的实例对象的写法,与ES5完全一样,也是使用 报错 var point = Point(2,3); 正确 var point = new Point(2,3); 与ES5一样,实例的属性除非显式定义在其本身(即定义在 与ES5一样,类的所有实例共享一个原型对象。 这也意味着,可以通过实例的 var p1 = ); var p2 = new Point(3,2); p1.__proto__.printName = function () { return 'Oops' }; p1.printName() "Oops" p2.printName() "Oops" var p3 = new Point(4,1)">); p3.printName() "Oops" 上面代码在 name属性由于本质上,ES6的Class只是ES5的构造函数的一层包装,所以函数的许多特性都被Class继承,包括 class Point {} Point.name "Point"
Class表达式与函数一样,Class也可以使用表达式的形式定义。 const MyClass = class Me { getClassName() { return Me.name; } }; 上面代码使用表达式定义了一个类。需要注意的是,这个类的名字是 let inst = MyClass(); inst.getClassName() Me Me.name ReferenceError: Me is not defined 上面代码表示, 如果Class内部没用到的话,可以省略 const MyClass = class { /* ... */ }; 采用Class表达式,可以写出立即执行的Class。 let person = class { constructor(name) { this.name = name; } sayName() { console.log(this.name); } }('张三'); person.sayName(); "张三" 上面代码中,person是一个立即执行的Class的实例。 不存在变量提升Class不存在变量提升(hoist),这一点与ES5完全不同。 new Foo(); ReferenceError class Foo {} 上面代码中, Class的继承基本用法Class之间可以通过 class ColorPoint extends Point {} 上面代码定义了一个 class ColorPoint extends Point { constructor(x,y,color) { super(x,y); 调用父类的constructor(x,y) this.color = color; } toString() { return this.color + ' ' + super.toString(); 调用父类的toString() } } 上面代码中, 子类必须在 class Point { */ } class ColorPoint extends Point { constructor() { } } let cp = new ColorPoint(); ReferenceError 上面代码中, 类的prototype属性和__proto__属性大多数浏览器的ES5实现之中,每一个对象都有 (1)子类的 (2)子类 class A { } class B extends A { } B.__proto__ === A true B.prototype.__proto__ === A.prototype true 上面代码中,子类 这样的结果是因为,类的继承是按照下面的模式实现的。 class A { } class B { } B的实例继承A的实例 Object.setPrototypeOf(B.prototype,A.prototype); B继承A的静态属性 Object.setPrototypeOf(B,A); Object.getPrototypeOf()
Object.getPrototypeOf(ColorPoint) === Point true 因此,可以使用这个方法判断,一个类是否继承了另一个类。 super关键字
(1)作为函数调用时(即 (2)作为对象调用时(即
原生构造函数的继承原生构造函数是指语言内置的构造函数,通常用来生成数据结构。ECMAScript的原生构造函数大致有下面这些。
以前,这些原生构造函数是无法继承的,ES6允许继承原生构造函数定义子类,因为ES6是先新建父类的实例对象 class MyArray extends Array { constructor(...args) { super(...args); } } var arr = MyArray(); arr[0] = 12; arr.length 1 arr.length = 0; arr[0] undefined 上面代码定义了一个 上面这个例子也说明, Class的静态方法类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上 class Foo { static classMethod() { return 'hello'; } } Foo.classMethod() 'hello' var foo = Foo(); foo.classMethod() TypeError: undefined is not a function 上面代码中, 父类的静态方法,可以被子类继承。 ; } } class Bar extends Foo { } Bar.classMethod(); 'hello' 上面代码中,父类 静态方法也是可以从 new.target属性
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 在BlazeDS与Flash间传送IMSQTI数据
- reactjs – intl.formatMessage不工作 – react-intl
- ruby-on-rails – 如何覆盖rails中的路径路径助手?
- STC12LE5052的EEPROM使用
- ruby-on-rails – self.send(method,=,value)不起作用
- c# – NHibernate投掷会话已关闭
- React Native 生成 released apk图片不显示
- reactjs – 在React.js表单组件中使用状态或引用?
- ruby-on-rails – Rails – 带有“dot”的参数(例如/google
- 以编程方式检测从C#代码中检出的当前git分支