JavaScript执行(三):你知道现在有多少种函数吗?
函数
在ES2018中,函数包含很多种类型:
普通函数:使用function关键字定义的函数
箭头函数:使用 => 运算符定义的函数
方法:在class中定义的函数
生成器函数:使用function*定义的函数
类:使用class定义的类,实际上也是函数
异步函数:普通函数、箭头函数和生成器函数加上async关键字
对普通变量来说,这些函数并没有本质区别,都是遵循了“继承定义时环境”的规则
this关键字
this是执行上下文中很重要的一个部分。同一个函数调用方式不同,得到的this值也不同。
this关键字的机制
函数能够引用定义时的变量,如上文分析,函数也能记住定义时的this,因此,函数内部必定有一个机制来保存这些信息。
在JavaScript标准中,为函数规定了用来保存定义时的上下文的私有属性[[environment]]。
当一个函数执行时,会创建一条新的执行环境记录,记录外层词法环境(out lexical environment)会被设置成函数的[[environment]]。这个动作叫做切换上下文。
JavaScript用一个栈来管理执行上下文,这个栈中的每一项又包含一个链表。
当函数调用时,会入栈一个新的执行上下文,函数调用结束,执行上下文会出栈。
而this则是一个更为复杂的机制,JavaScript标准定义了[[thisMode]]的私有属性。
[[thisMode]]私有属性有三个取值:
lexical:表示从上下文中找this,这对应了箭头函数。
global:表示this为undefined时,取全局对象,对应了普通函数。
strict: 当严格模式时使用,this严格按照调用时传入的值,可能为null或者undefined。
class设计成了默认按strict模式执行。
函数创建新的执行上下文中的词法环境记录时,会根据[[thisMode]]来标记新纪录的[[ThisBindingStatus]]私有属性。
代码执行遇到this时,会逐层检测当前词法环境记录中[[ThisBindingStatus]],当找到有this的环境记录时获取this的值。
操作this的内置函数
Function.prototype.call 和 Function.prototype.apply 可以指定函数调用时传入的this值:
function foo(a, b, c){
console.log(this);
console.log(a, b, c);
}
foo.call({}, 1, 2, 3);
foo.apply({}, [1, 2, 3]);
这里call和apply作用是一样的,只有传参方式有区别。
此外,Function.prototype.bind 它可以生成一个绑定的过的函数,这个函数的this值固定了参数:
function foo(a, b, c){
console.log(this);
console.log(a, b, c);
}
foo.bind({}, 1, 2, 3)();
此文章为7月Day8学习笔记,内容来源于极客时间《重学前端》,日拱一卒,每天进步一点点💪💪
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net