ES6 类

##1.ES6定义一个Point类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}

toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}

//实例化
var point = new Point(1,2);
point.toString()

构造函数的prototype属性,在ES6的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

1
2
3
4
5
6
7
8
9
10
11
12
class Point {
constructor(){}
toString(){}
toValue(){}
}

// 等同于

Point.prototype = {
toString(){},
toValue(){}
};

##2.类的继承
Class之间可以通过extends关键字实现继承

1
2
3
4
5
6
7
8
9
10
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}

toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}

上面代码中,constructor方法和toString方法之中,都出现了super关键字,它在这里表示父类的构造函数,用来新建父类的this对象。

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

另一个需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}

class ColorPoint extends Point {
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y);
this.color = color; // 正确
}
}

//实例化子类
let cp = new ColorPoint(25, 8, 'green');

CommonJS和ES6模块

CommonJS 模块及模块引用

1
2
3
4
// moduleA.js
module.exports = function( value ){
return value * 2;
}
1
2
3
// moduleB.js
var multiplyBy2 = require('./moduleA');
var result = multiplyBy2(4);

ES6 模块及模块引用

1
2
3
4
// moduleA.js
export function multiplyBy2( value ) {
return value * 2;
}
1
2
3
// moduleB.js
import multiplyBy2 from './moduleA.js';
var result = multiplyBy2(4);

CommonJS和ES6的模块的区别:

规范 暴露模块 引入模块
CommonJS module.exports require(‘..’)
ES6 export import A from ‘..’

一个ES6的暴露类和引用类的栗子:

1
2
3
4
5
// moduleA.js
export default class Action{
getter: function(){}
setter: function(){}
}

1
2
3
4
// moduleB.js
import Action from ./moduleA.js;
//实例化Action类
var action = new Action();

执行上下文this

this指向window的两种情况:1.new function 2.全局对象this

1
2
3
4
5
6
7
8
9
10
function func1(){
this.name = "jim";
console.log(this); //this 指向 window
}
function func2(){
console.log(this.name); //this 指向 window
}
func1();
func2();
console.log(this); //this 指向 window

通过构造器创建对象,this指向该创建的对象,如var harry = new Persion(‘Harry’,18,’female’),this指向harry对象

1
2
3
4
5
6
7
8
9
10
11
12
function Persion(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.changeAge = function(age){
this.age = age;
console.log(this); //this 指向 harry对象
}
console.log(this); //this 指向 harry对象
}
var harry = new Persion('Harry',18,'female');
harry.changeAge(22);

构造器和表达式

通过构造器创建的变量和表达式创建的变量,虽然值相同,但是构造器创建的变量类型是对象而表达式不是

1
2
3
4
5
var _bool = new Boolean(false); //_bool is Object
var _bool2 = false; //_bool is boolean
_bool == _bool2; //true
_bool === _bool2; //false
_bool.valueOf() === _bool2; //true

通过上述例子,我们看出new Boolean(false)创建的变量类型为object,原始值为false,原始值的类型是boolean,通过var _bool2 = false表达式赋值得到的变量类型是boolean。

相同的,通过new String()创建的变量也是object类型,表达式赋值的变量也是string类型

1
2
var _string = new String("this is string"); //_string is Object
var _string2 = "this is string"; //_string2 is string

冒泡与阻止冒泡

1
2
3
4
5
<div id="box">
<h1>标题标题标题标题标题标题标题标题</h1>
<img id="img_test" width="500px" height="300px" src="">
<p>这是段落这是段落这是段落这是段落这是段落这是段落这是段落这是段落这是段落</p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
(function(){
var __box = document.getElementById('box');
var __imgTest = document.getElementById('img_test');
__box.addEventListener('click',function(){
alert("点击box");
},false);
__imgTest.addEventListener('click',function(){
alert("点击选中图片");
window.event? window.event.cancelBubble = true : e.stopPropagation();
},false);
})();
</script>