ES6 tips
2017-10-27 本文已影响27人
别过经年
1. rest 可变长参数
redux 源码
//...middlewares就是可变长参数,但是在applyMiddleware拿到的middlewares是个数组
export function applyMiddleware(...middlewares: Middleware[]): GenericStoreEnhancer;
examples shopping-cart 调用的时候:
import thunk from 'redux-thunk'
const middleware = [ thunk ];
if (process.env.NODE_ENV !== 'production') {
middleware.push(createLogger());
}
const store = createStore(
reducer,
applyMiddleware(...middleware)//此处将middleware数组展开,变成一个个元素,
//不能直接在控制台输出...middleware,可以在[...middleware] {...middleware} applyMiddleware(...middleware)
)
2. 箭头函数真的只是this 和调用时的上下文无关,而是取决于定义时的上下文?
function make () {
return ()=>{
console.log(this);
}
}
const testFunc = make.call({ name:'foo' });
testFunc(); //=> { name:'foo' }
testFunc.call({ name:'bar' }); //=> { name:'foo' }
经过babel编译后的代码
'use strict';
function make() {
var _this = this;
return function () {
console.log(_this);//这里可以看出箭头函数很单纯,只是向上查找this,自己没有this
};
}
var testFunc = make.call({ name: 'foo' });
testFunc(); //=> { name:'foo' }
testFunc.call({ name: 'bar' }); //=> { name:'foo' }
引用b实际上箭头函数中并不只是 this 和普通函数有所不同,箭头函数中没有任何像 this 这样自动绑定的局部变量,包括:this,arguments,super(ES6),new.target(ES6)…… 在普通函数中,会自动绑定上的各种局部变量,箭头函数都是十分单纯的沿着作用域链向上寻找
3. ES6 super
事件起因是typescript官网的一段代码:
将基类构造函数的返回值作为'this'以前不知道constructor能自定义返回值,于是查了一下,加深了对super的理解
super有两种调用方式,一个是作为函数调用,一个是作为对象使用
1.作为函数调用:
必须在子类的构造函数中调用,否则会报错,constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
class Foo {
constructor() {
return Object.create(null);
}
}
new Foo() instanceof Foo
// false
2.super作为普通对象使用
super.p() 这种方式就指向了父类的prototype对象
但是现在任然不知道截图中的那段话是什么意思?!后续再看
4. es6 箭头函数和普通函数继承的区别
提示:箭头函数和继承指出:
如果你有一个实例方法是箭头函数那么它会保持 this。既然只有一个 this,这种函数不能使用 super 调用(super 只对原型成员有效)。你可以简单地在子类中重载它之前创建一个方法的副本来获得它。
class Adder {
constructor(public a: number) {}
// This function is now safe to pass around
add = (b: string): string => {
return this.a + b;
}
}
class ExtendedAdder extends Adder {
// Create a copy of parent before creating our own
private superAdd = this.add;
// Now create our override
add = (b: string): string => {
return this.superAdd(b);
}
}
稍微改造下:
class Adder {
constructor(public a: number) {}
// This function is now safe to pass around
add = (b: string): string => {
return this.a + b;
};
}
class ExtendedAdder extends Adder {
// Create a copy of parent before creating our own
private superAdd = this.add;
// Now create our override
add = (b: string): string => {
// return this.superAdd(b);
super.add("b");
};
}
var adder = new ExtendedAdder();
adder.add("nnn")
直接使用tsc执行,报错
- tempCodeRunnerFile.ts(13,3): error TS2425: Class 'Adder' defines instance member property 'add', but extended class 'ExtendedAdder' defines it as instance member function.
tempCodeRunnerFile.ts(15,11): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.
class B {
print = () => {
console.log('print b');
}
}
class D extends B {
print () {
super.print();
console.log('print d');
}
}
const d = new D();
d.print();
用ts运行,会报错:
- return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
tempCodeRunnerFile.ts(8,5): error TS2425: Class 'B' defines instance member property 'print', but extended class 'D' defines it as instance member function.
tempCodeRunnerFile.ts(9,10): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.
翻译过来就是 Class 'B'定义的print是实例属性,但是子类定义的print是实例方法,只有public and protected methods才能用super进行访问
但是上面的代码经过babel和ts分别编译后再去运行,控制台打印出print b