Javascript中的关键字的使用、工作原理及注意事项

根据这个位置来理解它,情况可以分为3种。

1。在函数中:这通常是一个隐式参数。

2、外部功能(最高水平的范围):在浏览器中,这指的是全局对象;在Node.js,它是指模块(模块)的出口(出口)。

3、通过对eval()的字符串:如果eval()是直接调用,这指的是当前的对象;如果是间接调用eval(),这意味着全球目标。

对于这些类别,我们已经做了相应的测试。
1。函数中的这个

功能基本上能代表JS所有的这种结构,所以这是用这种最常见的情形,和功能可分为三种角色。

真正的功能
构造函数
方法

1.1在实函数中

在一个实函数中,a的值取决于它所在的上下文的模式。

松散模式:这是指全局对象(在浏览器中是窗口)。

复制代码代码如下所示:
功能sloppyfunc(){
console.log(=窗口); / /真的
}
SloppyFunc();


严格模式:此值未定义。

复制代码代码如下所示:
功能strictfunc(){
严格使用;
console.log(=定义); / /真的
}
StrictFunc();


这是函数的隐式参数,所以它的值总是一样的,但是你可以通过调用()或应用()来定义这个值的值。

复制代码代码如下所示:
功能(arg1,arg2){函数
console.log(本); / / 1
console.log(arg1); / / 2
console.log(2); / / 3
}
func.call(1, 2, 3); / /(这,arg1,arg2)
func.apply(1,{ 2, 3 }); / /(这arraywithargs)


1.2个构造函数中的这个

新的操作可以创建一个新的对象,并通过这个对象将构造函数传递给构造函数。

复制代码代码如下所示:
Var savedThis;
功能化(){
这savedthis =;
}
VaR所=新的约束();
console.log(savedthis =院); / /真的


js中的新操作的实现可能如下面的代码所示(在这里实现更精确,这个实现也有点复杂):

复制代码代码如下所示:
函数算子不仅能够实现(建设,arraywithargs){
VaR以= object.create(建筑原型);
Constr.apply(这个,arraywithargs);
返回这个;
}


1.3种方法中的这一点

在这种方法中,这种用法更倾向于传统的面向对象语言:由该对象指示的接收者,即包含方法的对象。

复制代码代码如下所示:
var obj = { {
方法:函数(){
console.log(= obj); / /真的
}
}
Obj.method();


2。这在行动范围内

在浏览器中,作用域是全局作用域,这是指全局对象(如窗口):

复制代码代码如下所示:

console.log(=窗口); / /真的



在Node.js,你通常在模块执行的功能。因此,顶级作用域是一个非常特殊的模块(模块范围)范围:

复制代码代码如下所示:
全局(不是窗口)指的是全局对象:
console.log(数学=全球。数学); / /真的

这并不是指全局 /对象:
(这console.log!=全局)
引用模块的导出:
console.log(=模块。出口); / /真的


这3年,eval()

eval()可以直接调用(通过调用函数name'eval)或间接(称为通过其他方式,如电话())。更多详情,请看这个。

复制代码代码如下所示:
真正的函数
功能sloppyfunc(){
console.log(eval(本)=窗口); / /真的
}
SloppyFunc();

功能strictfunc(){
严格使用;
console.log(eval(本)=未定义); / /真的
}
StrictFunc();

构造函数
Var savedThis;
功能化(){
savedthis = eval(本);
}
VaR所=新的约束();
console.log(savedthis =院); / /真的

方法
var obj = { {
方法:函数(){
console.log(eval(本)= obj); / /真的
}
}
Obj.method();


4。与此相关的陷阱

您必须注意下面将介绍的3个陷阱。请注意,在下面的示例中,使用严格模式(严格模式)可以提高代码的安全性。因为在实际函数中,这个值是未定义的,当出现问题时,您将得到警告。

4.1忘记使用新的

如果不使用新来调用构造函数,则实际使用的是一个实函数,所以这不是您期望的值:

复制代码代码如下所示:
函数点(x,y){
这个;
这个,y = y;
}
var(= 7, 5);我们忘记了新的!
console.log(P =定义); / /真的

已创建变量:全局
console.log(x); / / 7
console.log(Y); / / 5


但是,如果您使用的是严格模式,您将得到一个警告(此=未定义的)。

复制代码代码如下所示:
函数点(x,y){
严格使用;
这个;
这个,y = y;
}
var =点(7, 5);
TypeError:不能设置property'x'of / /未定义


4.2不当使用方法

如果你得到的价值的一种方法(不直接称呼它),你用这个方法作为一个功能,你可能会这样做,当你要把一个方法为函数或调用的方法作为一个参数。这是setTimeout案例()和注册事件处理(事件处理程序)。我将称之为()来模拟这一场景的方法:

复制代码代码如下所示:
类似setTimeout(和) / *(setimmediate)
功能称之为(功能){
Func();
}


如果在草率模式下调用方法作为函数,则*指向全局对象,因此创建的所有变量都是全局变量。

复制代码代码如下所示:
var计数器{ {
计数:0,
草率的模式/方法
函数(){
这个数+ +;
}
}
CallIt(对公司);

没有工作:
console.log(计数器计数); / / 0

已经创建了一个全局变量
(楠是未定义的 +应用程序+的结果):
console.log(计数); / /南


如果你在严格模式下这样做,这是未定义的,你仍然得不到你想要的结果,但至少你会得到一个警告:

复制代码代码如下所示:
var计数器{ {
计数:0,
严格的模式/方法
函数(){
严格使用;
这个数+ +;
}
}
CallIt(对公司);

TypeError:不能读property'count'of / /未定义
console.log(计数器计数);


为了获得预期的结果,可以使用绑定():

复制代码代码如下所示:
var计数器{ {
计数:0,
函数(){
这个数+ +;
}
}
CallIt(counter.inc.bind(计数器));
它工作了!
console.log(计数器计数); / / 1


还创建一个函数,该函数总是将此值设置为计数器。

4.3隐藏这

当你在一个方法中使用一个函数时,你经常忽略函数有它自己的,这与方法不同,所以你不能把这两者混合在一起。

复制代码代码如下所示:
var obj = { {
名称:简,
朋友:{ 'tarzan ','cheeta},
循环:函数(){
严格使用;
This.friends.forEach(
函数(朋友){
console.log(这个名字+ 'knows +朋友);
}
);
}
};
Obj.loop();
TypeError:不能读property'name'of / /未定义


在上面的例子中,函数中的this.name不能使用,因为价值的功能这是不确定的,这是不同的从这个方法中的回路()。这是解决这个问题的三种方法:

1,=,将这个赋值给变量,以便显式地显示。(除此之外,自我也是存储这个的通用变量名),然后使用该变量。

复制代码代码如下所示:
循环:函数(){
严格使用;
var =;
this.friends.foreach(功能(朋友){)
Console.log(,'knows +姓名+朋友);
});
}


2,绑定()。使用绑定()来创建一个函数,这个函数的这个值总是要传递的值(在下面的例子中,方法是这个):

复制代码代码如下所示:
循环:函数(){
严格使用;
this.friends.foreach(功能(朋友){)
console.log(这个名字+ 'knows +朋友);
}绑定(这个);
}


3、使用foreach二参数,foreach二参数引入回调函数,作为这个回调函数。

复制代码代码如下所示:
循环:函数(){
严格使用;
this.friends.foreach(功能(朋友){)
console.log(这个名字+ 'knows +朋友);
},这个);
}


5,最佳实践

在理论上,我不认为真正属于自己的这个功能,和解决方案是基于这idea.ecmascript 6是使用功能的箭头(箭头功能)来达到这一效果,箭头的功能是没有这个功能,这种功能,你可以使用这个随便,和不要担心有一个隐含的存在。

复制代码代码如下所示:
循环:函数(){
严格使用;
参数(一)/是一个箭头的功能
this.friends.foreach(朋友= > {
循环的'这个' '这个'
console.log(这个名字+ 'knows +朋友);
});
}


我不喜欢一些API,这是一个额外的参数实际函数:

复制代码代码如下所示:
每个(函数(){()
this.addmatchers({
ToBeInRange:功能(开始、结束){

}
});
});


通过以主方式编写一个隐式参数,可以更好地理解代码,这也符合箭头函数。

复制代码代码如下所示:
每个(API = > {
api.addmatchers({
ToBeInRange(开始、结束){

}
});
});