这是JavaScript中最神秘的功能之一,在将对象方法分配给其他变量后,绑定(此关键字)将丢失
var john = {
name: 'John',
greet: function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
};
john.greet("Mark"); // Hi Mark, my name is John
var fx = john.greet;
fx("Mark"); // Hi Mark, my name is
Run Code Online (Sandbox Code Playgroud)
我的问题是:
1)作业背后发生了什么?var fx = john.greet; 是按价值复制还是按参考复制?fx和john.greet指向两个不同的功能,对吧?
2)因为fx是一个全局方法,所以范围链只包含全局对象.Variable对象中此属性的值是多少?
Viv*_*ath 13
john.greet("Mark")实际上调用一个函数.当你这样做时var fx = john.greet;,你得到了对该功能的引用.因此,当你打电话给它时,this并不是必然的john.你实际上做的是window.fx("Mark")等this为window对象.当你说它处于全球范围内时,你走在了正确的轨道上.在这个特定的实例中,全局对象是window,fx实际上也是如此window.fx.
如果有函数引用,则应使用call或者apply如果要设置值this.试着这样做:
fx.call(john, "Mark");
Run Code Online (Sandbox Code Playgroud)
在第一个参数call或apply是用于值this在函数调用的上下文.
编辑
有些人提到这里的真正问题可能是围绕对象文字与对象实例的混淆.您正在创建一个对象文字,其行为也类似于单身.您无法创建该对象的新实例.在这种情况下john是对该文字的引用.在该上下文this中,函数greet指的是对象文字本身.因此,当你打电话时john.greet("Mark"),this必然会john.
当您单独获取引用john.greet并将其分配给全局变量时,您实际上是这样做的:
var fx = function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,this是window,因为fx基本上window.fx(因为这里的全局对象是window.假设这个代码被包装在另一个函数中,那么全局对象将引用该函数.
如果要创建对象的多个实例,可以执行以下操作:
var Person = function(name) {
var self = this; //maintains a reference to the instance
this.name = name;
this.greet = function(name) {
alert("Hi " + name + ", my name is " + self.name);
}
}
var john = new Person("John");
john.greet("Mark"); // alerts "Hi Mark, my name is John"
var fx = john.greet;
fx("Mark"); // also alerts "Hi Mark, my name is John"
Run Code Online (Sandbox Code Playgroud)
这里,self变量(函数的本地)维护对实际实例的引用,因为您在this创建对象时将其绑定到它.
在Javascript中有许多与OOP相关的最佳实践.你可以谷歌找出(有很多链接).我建议特别是读道格拉斯克罗克福德的东西.
1)fx并且john.greet指的是相同的函数对象,对象的赋值操作,通过引用工作.
为原始值,比如String,Number,Boolean undefined或null,该值的副本将被制成.
2)该this值指的是全局对象.
该this值不是变量对象的属性,它与范围链无关,是一个特殊的保留字,并且在调用函数时隐式确定(您也可以通过call或显式设置它apply).
JavaScript内部处理一个Reference type由两个组件组成的基础对象和属性名称,当调用一个函数时,this通过获取基础对象(通过内部GetValue操作)隐式确定该值.
最后,this隐式设置的最后一种情况是当您使用new运算符调用函数时,this关键字将引用新创建的对象.
所以,简单地说,这里是如何this工作的含蓄:
1-当函数作为方法调用时(该函数作为对象的成员调用):
obj.method(); // 'this' inside method will refer to obj
Run Code Online (Sandbox Code Playgroud)
2- 正常函数调用:
myFunction(); // 'this' inside the function will refer to the Global object
// or
(function () {})();
Run Code Online (Sandbox Code Playgroud)
3-使用new操作员时:
var obj = new MyObj(); // 'this' will refer to a newly created object.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2884 次 |
| 最近记录: |