我注意到,似乎没有明确解释this
关键字是什么以及如何在Stack Overflow站点上的JavaScript中正确(和错误地)使用它.
我亲眼目睹了一些非常奇怪的行为,并且无法理解为什么会发生这种行为.
this
工作如何以及何时使用?
我可以用async
关键字将javascript函数标记为"async"(即返回一个promise).像这样:
async function foo() {
// do something
}
Run Code Online (Sandbox Code Playgroud)
箭头函数的等效语法是什么?
这个问题针对的是那些在即将到来的ECMAScript 6(Harmony)背景下已经考虑过代码风格并且已经使用过该语言的人.
有了() => {}
和function () {}
我们有两种非常相似的方法来编写ES6中的函数.在其他语言中,lambda函数通常通过匿名来区分自己,但在ECMAScript中,任何函数都可以是匿名的.这两种类型中的每一种都具有唯一的使用域(即,当this
需要明确地绑定或明确地不绑定时).在这些域之间存在大量的情况,其中任何一种符号都可以.
ES6中的箭头功能至少有两个限制:
new
this
在初始化时限制范围抛开这两个限制,箭头函数理论上几乎可以在任何地方替换常规函数.在实践中使用它们的正确方法是什么?是否应使用箭头功能,例如:
this
变量不可知,我们不创建对象.我正在寻找的是在ECMAScript的未来版本中选择适当的函数符号的指南.该指南需要明确,以便可以向团队中的开发人员讲授,并保持一致,这样就不需要从一个函数符号到另一个函数符号进行不断的重构.
javascript lambda ecmascript-harmony ecmascript-6 arrow-functions
我刚接触使用带有React的ES6类,之前我已经将我的方法绑定到当前对象(在第一个示例中显示),但ES6是否允许我使用箭头将类函数永久绑定到类实例?(当作为回调函数传递时很有用.)当我尝试使用它时,我遇到错误,就像使用CoffeeScript一样:
class SomeClass extends React.Component {
// Instead of this
constructor(){
this.handleInputChange = this.handleInputChange.bind(this)
}
// Can I somehow do this? Am i just getting the syntax wrong?
handleInputChange (val) => {
console.log('selectionMade: ', val);
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我要传递SomeClass.handleInputChange
给setTimeout
它,那么它将被限定为类实例,而不是window
对象.
在我看来,在ES6,下面的两个功能都非常接近相同的:
function () {
return this;
}.bind(this);
() => {
return this;
};
Run Code Online (Sandbox Code Playgroud)
最终结果看起来是一样的:箭头函数生成一个JavaScript函数对象,其this
上下文绑定到与this
创建它们的位置相同的值.
显然,在一般意义上,Function.prototype.bind
它比箭头函数更灵活:它可以绑定到本地以外的值this
,并且它可以this
在任何时间点绑定任何函数,可能在最初创建之后很长时间.不过,我不问如何bind
本身就是从箭头的功能不同,我问箭头的功能是如何从立即调用不同bind
使用this
.
ES6中的两个结构之间是否有任何差异?
简单的说...
为什么
setTimeout('playNote('+currentaudio.id+', '+noteTime+')', delay);
Run Code Online (Sandbox Code Playgroud)
完美地工作,在指定的延迟后调用函数,但是
setTimeout(playNote(currentaudio.id,noteTime), delay);
Run Code Online (Sandbox Code Playgroud)
同时调用函数playNote?
(这些setTimeout()s在for循环中)
或者,如果我的解释太难阅读,这两个函数之间有什么区别?
我不知道箭头函数是否绑定arguments
到词法范围.
看一下这个例子(可以使用相同的概念this
):
var b = function() { return () => console.log(arguments); };
b(1,2,3)(4,5,6); // different result of chrome vs FF.
Run Code Online (Sandbox Code Playgroud)
当我在Chrome上运行时,我得到了[1,2,3]
,但在Firefox上,我得到了[4,5,6]
.这是怎么回事?
当ES6箭头函数似乎不适用于使用prototype.object将函数赋值给对象时.请考虑以下示例:
function Animal(name, type){
this.name = name;
this.type = type;
this.toString = () => `${this.name} is a ${this.type}`;
}
var myDog = new Animal('Max', 'Dog');
console.log(myDog.toString()); //Max is a Dog
Run Code Online (Sandbox Code Playgroud)
在对象定义中显式使用箭头函数,但使用带有Object.prototype语法的箭头函数不会:
function Animal2(name, type){
this.name = name;
this.type = type;
}
Animal2.prototype.toString = () => `${this.name} is a ${this.type}`;
var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()); //is a undefined
Run Code Online (Sandbox Code Playgroud)
正如概念验证一样,使用带有Object.prototype语法的Template字符串语法可以正常工作:
function Animal3(name, type){
this.name = name;
this.type = type;
}
Animal3.prototype.toString = function(){ return `${this.name} is a ${this.type}`;}
var myPet3 …
Run Code Online (Sandbox Code Playgroud) 哪个更好:导出const
箭头函数,如下所示:
export const foo = () => 'bar'
Run Code Online (Sandbox Code Playgroud)
或导出常规函数,如下所示:
export function baz() {
return 'bar';
}
Run Code Online (Sandbox Code Playgroud)
他们编译如下:
exports.baz = baz;
function baz() {
return 'bar';
}
var foo = exports.foo = function foo() {
return 'bar';
};
Run Code Online (Sandbox Code Playgroud)
看起来使用const /箭头函数组合声明了一个额外的变量(foo
),这似乎是简单函数声明的一个不必要的额外步骤.
javascript ×9
ecmascript-6 ×6
babeljs ×2
async-await ×1
lambda ×1
promise ×1
prototype ×1
reactjs ×1
scoping ×1
settimeout ×1
this ×1