Javascript的这
考虑以下功能:
函数foo(){console.log(“bar”);console.log(this);}foo();//调用函数
请注意,我们是在正常模式下运行的,即不使用严格模式。
在浏览器中运行时这
将被记录为窗口
。这是因为窗口
是web浏览器作用域中的全局变量。
如果您在node.js这样的环境中运行这段代码,这
将引用应用程序中的全局变量。
现在,如果我们通过添加语句在严格模式下运行它“使用严格”;
到函数声明的开头,这
将不再提及任何一个环境中的全局变量。这样做是为了避免严格模式中的混淆。这
在这种情况下会记录未定义
,因为这就是它的本质,所以它没有定义。
在以下情况中,我们将了解如何操作这
.
有不同的方法可以做到这一点。如果您在Javascript中调用了本机方法,如对于每个
和片
,您应该已经知道这
在这种情况下,变量是指对象
在其中调用该函数(请注意,在javascript中,几乎所有内容都是对象
,包括阵列
s和功能
s) ●●●●。以下面的代码为例。
var myObj={key:“Obj”};myObj.logThis=函数(){//我是一种方法console.log(this);}myObj.logThis();//myObj已被记录
如果对象
包含一个包含功能
,该属性称为方法。此方法在调用时将始终具有这
变量设置为对象
它与关联。这对严格和非严格模式都适用。
注意,如果一个方法存储(或者说复制)在另一个变量中这
不再保留在新变量中。例如:
//继续前面的代码片段var myVar=myObj.thisMethod;myVar();//根据操作模式记录window/global/undefined
考虑一个更常见的实际场景:
var el=文档.getElementById('idOfEl');el.addEventListener('click',function(){console.log(this)});//addEventListener调用的函数将其作为对元素的引用//所以点击元素就会记录该元素本身
考虑Javascript中的构造函数:
职能人员(姓名){this.name=名称;this.sayHello=函数(){console.log(“你好”,这个);}}var awal=新人员(“awal”);awal.sayHello();//在`awal.sayHello`中,`this`包含对变量`awal的引用`
这是如何工作的?好吧,让我们看看当我们使用新的
关键字。
- 使用调用函数
新的
关键字将立即初始化对象
类型为人
.
- 此的构造函数
对象
将其构造函数设置为人
此外,请注意水洼类型
会回来的对象
只有。
- 这个新的
对象
将被指定为人员.原型
。这意味着人
原型将可用于以下所有实例人
,包括阿瓦尔
.
- 功能
人
其本身现在被调用;这
是对新构建对象的引用阿瓦尔
.
挺直的,嗯?
请注意,官方的ECMAScript规范nowhere声明这些类型的函数是实际的建造师
功能。它们只是正常的功能,并且新的
可用于任何函数。只是我们这样使用它们,所以我们只把它们称为这样。
所以是的,因为功能
s也是物体
(实际上是Javascript中的第一类变量),甚至函数也有。。。好吧,它们自己的功能。
所有函数都继承自全局功能
,它的许多方法中有两种是呼叫
和应用
,两者都可以用于操作这
在调用它们的函数中。
函数foo(){console.log(this,arguments);}var thisArg={myObj:“很酷”};foo.调用(thisArg,1,2,3);
这是使用呼叫
。它基本上取第一个参数并设置这
在函数中foo公司
作为参考这个Arg
。传递给的所有其他参数呼叫
传递给函数foo公司
作为参数。
因此上述代码将记录{myObj:“很酷”},[1,2,3]
在控制台中。更改这
在任何功能中。
应用
几乎与呼叫
接受它只需要两个参数:这个Arg
以及一个数组,其中包含要传递给函数的参数。所以上面的呼叫
调用可以转换为应用
这样地:
foo.apply(thisArg,[1,2,3])
请注意呼叫
和应用
可以覆盖的值这
我们在第二个项目符号中讨论了逐点设置方法调用。足够简单:)
绑定
是的兄弟呼叫
和应用
。它也是由全局功能
Javascript中的构造函数。两者之间的差异绑定
和呼叫
/应用
两者都是吗呼叫
和应用
将实际调用该函数。绑定
另一方面,使用这个Arg
和论据
预设。让我们举一个例子来更好地理解这一点:
函数foo(a,b){console.log(this,参数);}var thisArg={myObj:“现在更酷了”};var绑定=foo.bind(thisArg,1,2);console.log(绑定类型);//日志`函数`console.log(绑定);/*日志`函数(){本机代码}`*/bound();//调用`.bind返回的函数`//logs`{myObj:“现在更酷了”},[1,2]`
看到三者之间的区别了吗?这是微妙的,但它们的用法不同。喜欢呼叫
和应用
,绑定
也会超过这
通过点方法调用设置。
还要注意,这三个函数都不会对原始函数进行任何更改。呼叫
和应用
将从新构造的函数返回值,而绑定
将返回新构造的函数本身,以便调用。
有时,你不喜欢这样的事实这
更改范围,特别是嵌套范围。看看下面的例子。
var myObj={您好:函数(){返回“世界”},myMethod:函数(){//复制这个,变量名是区分大小写的var THIS=此;//回调ftw-o/foo.bar(“args”,函数(){//我想在这里打“你好”this.hello();//错误//但‘这’指的是‘foo’该死!//哦,等等,我们有备份/THIS.hello();//“世界”});}};
在上面的代码中,我们看到这
使用嵌套范围进行了更改,但我们希望这
从原来的范围。所以我们“复制”了这
到这个
并使用副本而不是这
.聪明,嗯?
索引:
- 保存在中的内容
这
默认情况下?
- 如果我们用Object-dot符号将函数作为方法调用会怎么样?
- 如果我们使用
新的
关键字?
- 我们如何操作
这
具有呼叫
和应用
?
- 使用
绑定
.
- 正在复制
这
解决嵌套范围问题。
……不需要鼓掌