ECMAScript 6 类 应用
2016-03-07 16:08
281 查看
近些日子在git上经常看到以es6编写的js代码。
以前有些了解,但没有深入学习。
现在用的人多了,也就找了些时间来学习了下。
应用:
在webpack 中会使用es6。
当然肯定需要模块来翻译成es5的代码:babel
es6文档看了下,我觉得对于类模块这块用处比较大。
在现实中使用也简单方便些。
js 语言传统是通过构造函数,定义并生成新对象。
在es6中引用了class 类。作为对象的模板。通过class关键字,定义类。
新的class写法只是让对象原型的写法更新清晰、更像面向对象编程的语法而以。
和后端写法类似了。
constructor j 是构造函数,this 表示实例对象。tostring 是类的方法。
方法的定义 实现是扩展了Point.prototype
实例对象:
var a=new Point(参数)
Point .name //Point
Class 表达式:
以上创建了一个类,类名是MyClass而不是Me. me只能在类的内部代码可用。
当然me是可以省略的
采用class 表达式,可以写出立即执行的class
class 不存在变量提升,
class 继承
class之间可以通过extends关键字实现继承。
上面定义了一个colorpoint 类,继承了point类的所有属性和方法。
但是由于没有部署任何任何,所以这两个类完全一样。等于复制了一个point。
上面代码定义了新的构造函数,和tostring方法。
方法内的super指向父类的方法。
class 的取值函数get和存值函数set
class的静态方法
staitc可以创建静态方法或属性。
模块的定义和引用。
js一直没有模块体系,无法将一个大程序拆分成互相依赖的小文件。
在es6之前社区制定了一些模块加载方案,最主要的有commonjs 和amd 两种。
前者用于服务器,后者用于浏览器
es6实现了模块功能,完全可以取代commonjs amd规范。
es6模块的设计思想,是尽量的静态化。使得编译时就能确定模块的依赖关系。
以及输入和输出的变量。
上面代码的实质是整体加载fs模块,生成一个对象。然后从这个对象上获取三个方法。这种加载为“运行时加载”
因为只有运行时才能得到这个对象,导致完全没有办法 在编译时做“静态优化”
es6模块不是对象,而是通过export命令显式指定输出的代码,输出时采用静态命令的形式。
上面是加载fs模块的三个方法,其他方法不加载。
称为“编译加载”,即es6在编译时就完成模块加载。
当然这也导致了没法引用es模块本身,因为它不是对象。
export 命令
模块功能主要由export 和Import 。
export 命令用于规定模块的对外接口。
Import 命令用于输入其他模块提供的功能。
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。
如果你希望外部能够读取模块内部的某个变量,就必须使用export 输出该变量。
对外输出三个变量。
也可以这样写。
使用大括号指定要输出的一组变量。
还可以输出函数或类。
export输出的变量就是本来的名字,但是 可以使用as 重合名。
export语句输出的值是动态绑定,绑定其所在的模块。
上在代码输出变量foo 什为bar ,500ms后变成baz
import 命令
js文件可通过import命令加载这个模块。
import 命令接受一个对象,里面指定要多其他模块导入的变量名。
大括号里的变量名,必须与被导入模块对外接口名称相同。
as 可将输入的的名称,从命名。
import 命令具有提升效果,会提升到整个模块的头部,首先执行。
上面代码不会报错,因为Import 的执行早于foo的调用。
模块中可以先输入加载模块,再输出此模块
export 输出和import输入可以结合一起。
模块的整体加载
除了指定加载某个输出值,还可以使用整体加载,即用* 指定一个对象,所有输出值都加载在这个对象上面。
输出三个方法。
上面写法是指定要加载的方法,整体加载如下:
export default 命令
import命令使用时,用户需要知道所需加载的变量名,否则无法加载。
但为了方便,可以用default 命令,为模块指定默认输出。
默认输出一个函数
加载时import 可以为默认函数指定任意的名称。
需要注意的是,这时Import命令后面,不使用大括号 。
default 命令用在非匿名函数前,也是可以的。
本质上export default 就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。
因为export default 命令其实中是输出一个叫做default的变量,所以它后面不能跟变量声明语句。
可以在一条import语句中,同时输入默认方法和其他变量。
模块的继承
模块间可以继承
以上继承了circle模块。
export * 表示输出circle 模块的所有属性和方法,当然它会忽略default。
可以将circle 改名后再输出 。
加载模块再定义新引入对象,再获取模块的默认方法定义成exp
es6模块加载的实质
es6模块加载的机制,与commonjs模块完全不同。
commonjs模块输出的是一个值的拷贝,而es模块输出的是值的引用。
拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
lib加载以后,它的内部变化就不影响输出的counter了。这是因为mod.counter是一个原始类型的值,会被缓存。
es6模块的运行机制,与commonjs不一样。
它遇到模块加载命令Import时,不会执行模块,而是只生成一个动态的只读引用。
等到真的需要用到时,再到模块里去取值。
es6输出有点像地址引用,原始值变了,输入的值也会变。
因此es6模块是动态引用,模块里的变量绑定其白发在的模块。
由于es6输入的模块变量,只是一个“符号连接”,所以这个变量是只读的。对它进行重新赋值会报错。
以前有些了解,但没有深入学习。
现在用的人多了,也就找了些时间来学习了下。
应用:
在webpack 中会使用es6。
当然肯定需要模块来翻译成es5的代码:babel
es6文档看了下,我觉得对于类模块这块用处比较大。
在现实中使用也简单方便些。
js 语言传统是通过构造函数,定义并生成新对象。
在es6中引用了class 类。作为对象的模板。通过class关键字,定义类。
新的class写法只是让对象原型的写法更新清晰、更像面向对象编程的语法而以。
和后端写法类似了。
//定义类 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
constructor j 是构造函数,this 表示实例对象。tostring 是类的方法。
方法的定义 实现是扩展了Point.prototype
实例对象:
var a=new Point(参数)
Point .name //Point
Class 表达式:
const MyClass = class Me { getClassName() { return Me.name; } };
以上创建了一个类,类名是MyClass而不是Me. me只能在类的内部代码可用。
let inst = new MyClass(); inst.getClassName() // Me
当然me是可以省略的
const MyClass = class { /* ... */ };
采用class 表达式,可以写出立即执行的class
let person = new class { constructor(name) { this.name = name; } sayName() { console.log(this.name); } }("张三"); person.sayName(); // "张三"
class 不存在变量提升,
class 继承
class之间可以通过extends关键字实现继承。
class ColorPoint extends Point {}
上面定义了一个colorpoint 类,继承了point类的所有属性和方法。
但是由于没有部署任何任何,所以这两个类完全一样。等于复制了一个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() } }
上面代码定义了新的构造函数,和tostring方法。
方法内的super指向父类的方法。
class 的取值函数get和存值函数set
class MyClass { constructor() { // ... } get prop() { return 'getter'; } set prop(value) { console.log('setter: '+value); } } let inst = new MyClass(); inst.prop = 123; // setter: 123 inst.prop
class的静态方法
class Foo { static classMethod() { return 'hello'; } } Foo.classMethod() // 'hello' var foo = new Foo(); foo.classMethod() // TypeError: undefined is not a function
staitc可以创建静态方法或属性。
模块的定义和引用。
js一直没有模块体系,无法将一个大程序拆分成互相依赖的小文件。
在es6之前社区制定了一些模块加载方案,最主要的有commonjs 和amd 两种。
前者用于服务器,后者用于浏览器
es6实现了模块功能,完全可以取代commonjs amd规范。
es6模块的设计思想,是尽量的静态化。使得编译时就能确定模块的依赖关系。
以及输入和输出的变量。
// CommonJS模块 let { stat, exists, readFile } = require('fs'); // 等同于 let _fs = require('fs'); let stat = _fs.stat, exists = _fs.exists, readfile = _fs.readfile;
上面代码的实质是整体加载fs模块,生成一个对象。然后从这个对象上获取三个方法。这种加载为“运行时加载”
因为只有运行时才能得到这个对象,导致完全没有办法 在编译时做“静态优化”
es6模块不是对象,而是通过export命令显式指定输出的代码,输出时采用静态命令的形式。
// ES6模块 import { stat, exists, readFile } from 'fs';
上面是加载fs模块的三个方法,其他方法不加载。
称为“编译加载”,即es6在编译时就完成模块加载。
当然这也导致了没法引用es模块本身,因为它不是对象。
export 命令
模块功能主要由export 和Import 。
export 命令用于规定模块的对外接口。
Import 命令用于输入其他模块提供的功能。
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。
如果你希望外部能够读取模块内部的某个变量,就必须使用export 输出该变量。
// profile.js export var firstName = 'Michael'; export var lastName = 'Jackson'; export var year = 1958;
对外输出三个变量。
// profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export {firstName, lastName, year};
也可以这样写。
使用大括号指定要输出的一组变量。
export function multiply (x, y) { return x * y; };
还可以输出函数或类。
function v1() { ... } function v2() { ... } export { v1 as streamV1, v2 as streamV2, v2 as streamLatestVersion };
export输出的变量就是本来的名字,但是 可以使用as 重合名。
export var foo = 'bar'; setTimeout(() => foo = 'baz', 500);
export语句输出的值是动态绑定,绑定其所在的模块。
上在代码输出变量foo 什为bar ,500ms后变成baz
import 命令
js文件可通过import命令加载这个模块。
// main.js import {firstName, lastName, year} from './profile'; function setName(element) { element.textContent = firstName + ' ' + lastName; }
import 命令接受一个对象,里面指定要多其他模块导入的变量名。
大括号里的变量名,必须与被导入模块对外接口名称相同。
import { lastName as surname } from './profile';
as 可将输入的的名称,从命名。
import 命令具有提升效果,会提升到整个模块的头部,首先执行。
foo(); import { foo } from 'my_module';
上面代码不会报错,因为Import 的执行早于foo的调用。
export { es6 as default } from './someModule'; // 等同于 import { es6 } from './someModule'; export default es6;
模块中可以先输入加载模块,再输出此模块
export 输出和import输入可以结合一起。
import 'lodash'
模块的整体加载
除了指定加载某个输出值,还可以使用整体加载,即用* 指定一个对象,所有输出值都加载在这个对象上面。
export function area(radius) { return Math.PI * radius * radius; } export function circumference(radius) { return 2 * Math.PI * radius; }
输出三个方法。
// main.js import { area, circumference } from './circle'; console.log("圆面积:" + area(4)); console.log("圆周长:" + circumference(14));
上面写法是指定要加载的方法,整体加载如下:
import * as circle from './circle'; console.log("圆面积:" + circle.area(4)); console.log("圆周长:" + circle.circumference(14));
export default 命令
import命令使用时,用户需要知道所需加载的变量名,否则无法加载。
但为了方便,可以用default 命令,为模块指定默认输出。
// export-default.js export default function () { console.log('foo'); }
默认输出一个函数
// import-default.js import customName from './export-default'; customName(); // 'foo'
加载时import 可以为默认函数指定任意的名称。
需要注意的是,这时Import命令后面,不使用大括号 。
// export-default.js export default function foo() { console.log('foo'); } // 或者写成 function foo() { console.log('foo'); } export default foo;
default 命令用在非匿名函数前,也是可以的。
// 输出 export default function crc32() { // ... } // 输入 import crc32 from 'crc32'; // 输出 export function crc32() { // ... }; // 输入 import {crc32} from 'crc32';
// modules.js function add(x, y) { return x * y; }; export {add as default}; // 等同于 // export default add; // app.js import { default as xxx } from 'modules'; // 等同于 // import xxx from 'modules';
本质上export default 就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。
// 正确 export var a = 1; // 正确 var a = 1; export default a; // 错误 export default var a = 1;
因为export default 命令其实中是输出一个叫做default的变量,所以它后面不能跟变量声明语句。
import customName, { otherMethod } from './export-default';
可以在一条import语句中,同时输入默认方法和其他变量。
模块的继承
模块间可以继承
// circleplus.js export * from 'circle'; export var e = 2.71828182846; export default function(x) { return Math.exp(x); }
以上继承了circle模块。
export * 表示输出circle 模块的所有属性和方法,当然它会忽略default。
export { area as circleArea } from 'circle';
可以将circle 改名后再输出 。
import * as math from "circleplus"; import exp from "circleplus"; console.log(exp(math.e));
加载模块再定义新引入对象,再获取模块的默认方法定义成exp
import * as math from "circleplus"; import exp from "circleplus"; console.log(exp(math.e));
import * as math from "circleplus"; import exp from "circleplus"; console.log(exp(math.e));
es6模块加载的实质
es6模块加载的机制,与commonjs模块完全不同。
commonjs模块输出的是一个值的拷贝,而es模块输出的是值的引用。
拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
// lib.js var counter = 3; function incCounter() { counter++; } module.exports = { counter: counter, incCounter: incCounter, };
// main.js var mod = require('./lib'); console.log(mod.counter); // 3 mod.incCounter(); console.log(mod.counter); // 3
lib加载以后,它的内部变化就不影响输出的counter了。这是因为mod.counter是一个原始类型的值,会被缓存。
es6模块的运行机制,与commonjs不一样。
它遇到模块加载命令Import时,不会执行模块,而是只生成一个动态的只读引用。
等到真的需要用到时,再到模块里去取值。
es6输出有点像地址引用,原始值变了,输入的值也会变。
因此es6模块是动态引用,模块里的变量绑定其白发在的模块。
// lib.js export let counter = 3; export function incCounter() { counter++; } // main.js import { counter, incCounter } from './lib'; console.log(counter); // 3 incCounter(); console.log(counter); // 4
// m1.js
export var foo = 'bar'; setTimeout(() => foo = 'baz', 500);
// m2.js
import {foo} from './m1.js';
console.log(foo);
setTimeout(() => console.log(foo), 500);
// lib.js export let obj = {}; // main.js import { obj } from './lib'; obj.prop = 123; // OK obj = {}; // TypeError
由于es6输入的模块变量,只是一个“符号连接”,所以这个变量是只读的。对它进行重新赋值会报错。
相关文章推荐
- hrbust 哈理工oj 2113 Count【STL水题】
- 排序算法:希尔排序
- Gallery与ImageSwitch实现照片的预览功能
- 从这里开始,零度的追逐
- 第二章笔记
- C语言中改变字体颜色和背景的方法
- QT学习第一节
- 排序算法:希尔排序
- 简析类与对象,组合类,派生类的初始化过程
- NestedScrollView嵌套ViewPager
- Win8.1系统安装软件时报错called runscript when...解决方法
- NestedScrollView嵌套ViewPager
- js数组排序神器
- PAT (Basic Level)1029. 旧键盘
- if语句的用法及其案例
- postgresql Delete+ join
- bigbluebutton开发
- Java类与对象的一些想法
- graphx中Pregel函数详解
- selenium 'NoSuchElementException'