-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
es6必会之arrow functions #109
Comments
Arrow Function
基本用法
(foo, bar, baz) => { statements }
(foo, bar, baz) => { return expression } // (foo, bar, baz) => expression
( foo ) => { statements } // foo => { statements }
() => { statements } 高级用法
(foo, bar, baz) => ({a: 'a'})
(foo, bar, ...rest) => { statements }
(foo = 'foo', bar = true, bar = {a: 1, b: 2}) => { statements }
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a +b +c;
f(); // 6 关于Arrow functions,mozilla.org上有一篇深度剖析的文章。ES6 In Depth: Arrow functions Descriptionshorter functionsvar elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
elements.map(function(element ) {
return element.length;
}); // [8, 6, 7, 9]
elements.map(element => element.length); // [8, 6, 7, 9]
elements.map(({ length }) => length); // [8, 6, 7, 9] 其实最后2步做了这样一个操作: No thisjs中this,其实是与面向对象编程的思想不符的,箭头函数一定程度上消除了这种困惑。 function Person() {
this.age = 0;
setInterval(function growUp() {
this.age++;
console.log(this); // window
}, 1000);
}
var p = new Person(); function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
that.age++;
console.log(this, that); // window, Person实例(创建2个则打印2个)
}, 1000);
}
var p = new Person(); function Person(){
this.age = 0;
setInterval(() => {
this.age++;
console.log(this); // Person实例(创建2个则打印2个)
}, 1000);
}
var p = new Person();
console.log(p); 使用箭头函数后,callback中的this不再由于闭包而指向window,直接指向了当前实例,因此也不需要像es5中的var that = this;显式将实例传入callback中。 strict mode Arrow Functions严格模式下,箭头函数中的this也是ok的。 var f = () => { 'use strict'; return this; };
f() === window; // f() -> window 严格模式下,普通函数中的this是undefined。 var f = function() {'use strict'; return this; };
f() === undefined; //f() -> undefined 非严格模式下,this是window。 var f = function() { return this; };
f() === window; //f() -> window 显然箭头函数是strict mode下的更好写法。 通过call or apply调用Arrow Functions由于call()或者apply()只能通过parameters传值,所以在箭头函数上用call(),apply(),this会被忽略。因为箭头函数没有arguments!。 var adder = {
base: 1,
add: function(a) {
var f = v => v + this.base; // {base: 1, add: ƒ, addThruCall: ƒ}
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base; // {base: 1, add: ƒ, addThruCall: ƒ}
var b = {
base: 2
}
return f.call(b, a);
}
}
console.log(adder.add(1)); // 2
console.log(adder.addThruCall(1)); // 2,因为箭头函数没有arguments,call中的this会被忽略,this依然是当前的对象,因此还是2. 箭头函数中真的没有arguments吗?const f = function() { console.log(arguments) };
f(); Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ] const f = () => { console.log(arguments); }
f(); Uncaught ReferenceError: arguments is not defined arguments是enclosing scope的referencevar arguments = [1, 2, 3];
var arr = () => arguments[0];
arr(); // 1
function foo(n) {
var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
return f();
}
foo(3); // 6 通过 var customArguments = [1, 2, 3];
var arr = () => arguments[0];
arr(); // 1
function foo(n) {
var f = (...args) => args[0] + n;
return f(customArguments[0]);
}
foo(3); // 4 Arrow functions作为methods使用(慎用)在有this的情况下慎用,最好用function的shorthand。 'use strict';
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this);
}
}
obj.b(); // prints 0, Window {...}
obj.c(); // prints 10, Object {...} Object.defineProperty()中也可以说明箭头函数作为method不好。 'use strict';
var obj = {
a: 10
};
Object.defineProperty(obj, 'b', {
get: () => {
console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object)
return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
}
}); 改成get()是OK的。 使用new操作符箭头函数不能被当做constructor使用,否则会抛出一个错误。 var Foo = () => {};
var foo = new Foo(); // Uncaught TypeError: Foo is not a constructor
使用原型链上的方法var Foo = () => {};
console.log(Foo.prototype);// undefined function类型的可以。 var Foo= function() {};
console.log(Foo.prototype); // {constructor: ƒ} 没有constructor,没有prototype,这也是不能使用new的原因。 Function body
为什么{object: literal}必须用()返回?因为直接写一个{ foo: 1},foo: 1会被当作一个statement。 var func = () => { foo: 1 };
var func = () => { foo: function() {} }; foo会被当作label,1和function(){}被当作statement,没有任何return。 var func = () => ({foo: 1}); Arrow Function可以包含换行符吗?不可以。 var func = ()
=> 1;
// SyntaxError: expected expression, got '=>' 箭头函数的解析顺序是怎样的?let callback;
callback = callback || function() {}; // ok
callback = callback || () => {};
// SyntaxError: invalid arrow-function arguments
callback = callback || (() => {}); // ok 一些有趣的箭头函数用法
let empty = () => {}; (() => 'foobar')(); var simple = a => a > 15 ? 15: a;
let max = (a, b) => a > b ? a : b; var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b); // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] promise.then(foo => {
// ...
}).then(bar => {
// ...
}); setTimeout( () => {
console.log('I happen sooner');
setTimeout( () => {
console.log('I happen later');
}, 1);
}, 1); |
Vue中的箭头函数原型链方法// main.js
Vue.prototype.$appName = ()=> {
console.log(this); // 绑定的this指向的是main.js
} Vue.prototype.$appName = function(){
console.log(this); // 这样才能绑定到Vue类,从而切换this到实例
} 单文件组件中的箭头函数vue实例除了watcher以外,几乎所有的地方都是箭头函数,这样才可以获取到单文件组件这个实例。从这里可以看出,其实箭头函数的作用是:隐式绑定this到父作用域。这里的父作用域指的是单文件组件实例。 为什么watcher不能是箭头函数?因为箭头函数中的this指向的是全局对象,不能指向当前vue实例。 |
与let,const一样,对箭头函数的掌握也一直是模棱两可,因此需要深入学习一下,mdn的Arrow Functions就是很好的学习资料,除了阅读文档,我也会加入一些自己的思考。
The text was updated successfully, but these errors were encountered: