We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
看看这个有着深不可测的魔力的this到底是个什么玩意儿 ~
this
在传统面向对象的语言中,比如Java,this关键字用来表示当前对象本身,或当前对象的一个实例,通过this关键字可以获得当前对象的属性和调用方法。
在JavaScript中,this似乎表现地略有不同,这也是让人“讨厌”的地方~
ECMAScript规范中这样写:
this 关键字执行为当前执行环境的 ThisBinding。
MDN上这样写:
In most cases, the value of this is determined by how a function is called. 在绝大多数情况下,函数的调用方式决定了this的值。
可以这样理解,在JavaScript中,this的指向是调用时决定的,而不是创建时决定的,这就会导致this的指向会让人迷惑,简单来说,this具有运行期绑定的特性。
参考资料:this - JavaScript | MDN
来看看不同的情况五花八门的this吧~
首先需要理解调用位置,调用位置就是函数在代码中被调用的位置,而不是声明的位置。
通过分析调用栈(到达当前执行位置所调用的所有函数)可以找到调用位置。
function baz(){ console.log("baz"); bar(); } function bar(){ console.log("bar"); foo(); } function foo(){ console.log("foo"); } baz();
当我们调用baz()时,它会以此调用baz()→bar()→foo()。
baz()
bar()
foo()
对于foo():调用位置是在bar()中。 对于bar():调用位置是在baz()中。 而对于baz():调用位置是全局作用域中。
可以看出,调用位置应该是当前正在执行的函数的前一个调用中。
在全局执行上下文中this都指代全局对象。
window
var
this.
winodw.
console.log(window === this); // true var a = 1; this.b = 2; window.c = 3; console.log(a + b + c); // 6
在浏览器里面this等价于window对象,如果你声明一些全局变量,这些变量都会作为this的属性。
在函数内部,this的值取决于函数被调用的方式。
this指向全局变量。
function foo(){ return this; } console.log(foo() === window); // true
this指向绑定的对象上。
var person = { name: "axuebin", age: 25 }; function say(job){ console.log(this.name+":"+this.age+" "+job); } say.call(person,"FE"); // axuebin:25 say.apply(person,["FE"]); // axuebin:25
可以看到,定义了一个say函数是用来输出name、age和job,其中本身没有name和age属性,我们将这个函数绑定到person这个对象上,输出了本属于person的属性,说明此时this是指向对象person的。
say
name
age
job
person
如果传入一个原始值(字符串、布尔或数字类型)来当做this的绑定对象, 这个原始值会被转换成它的对象形式(new String()),这通常被称为“装箱”。
new String()
call和apply从this的绑定角度上来说是一样的,唯一不同的是它们的第二个参数。
call
apply
this将永久地被绑定到了bind的第一个参数。
bind
bind和call、apply有些相似。
var person = { name: "axuebin", age: 25 }; function say(){ console.log(this.name+":"+this.age); } var f = say.bind(person); console.log(f());
所有的箭头函数都没有自己的this,都指向外层。
关于箭头函数的争论一直都在,可以看看下面的几个链接:
ES6 箭头函数中的 this?你可能想多了(翻译)
关于箭头函数this的理解几乎完全是错误的 #150
MDN中对于箭头函数这一部分是这样描述的:
An arrow function does not create its own this, the this value of the enclosing execution context is used. 箭头函数会捕获其所在上下文的this值,作为自己的this值。
function Person(name){ this.name = name; this.say = () => { var name = "xb"; return this.name; } } var person = new Person("axuebin"); console.log(person.say()); // axuebin
箭头函数常用语回调函数中,例如定时器中:
function foo() { setTimeout(()=>{ console.log(this.a); },100) } var obj = { a: 2 } foo.call(obj);
附上MDN关于箭头函数this的解释:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions#不绑定_this
this指向调用函数的对象。
var person = { name: "axuebin", getName: function(){ return this.name; } } console.log(person.getName()); // axuebin
这里有一个需要注意的地方。。。
var name = "xb"; var person = { name: "axuebin", getName: function(){ return this.name; } } var getName = person.getName; console.log(getName()); // xb
发现this又指向全局变量了,这是为什么呢?
还是那句话,this的指向得看函数调用时。
this被绑定到正在构造的新对象。
通过构造函数创建一个对象其实执行这样几个步骤:
所以this就是指向创建的这个对象上。
function Person(name){ this.name = name; this.age = 25; this.say = function(){ console.log(this.name + ":" + this.age); } } var person = new Person("axuebin"); console.log(person.name); // axuebin person.say(); // axuebin:25
this指向触发事件的元素,也就是始事件处理程序所绑定到的DOM节点。
var ele = document.getElementById("id"); ele.addEventListener("click",function(e){ console.log(this); console.log(this === e.target); // true })
this指向所在的DOM元素
<button onclick="console.log(this);">Click Me</button>
在许多情况下JQuery的this都指向DOM元素节点。
$(".btn").on("click",function(){ console.log(this); });
如果要判断一个函数的this绑定,就需要找到这个函数的直接调用位置。然后可以顺序按照下面四条规则来判断this的绑定对象:
new
注意:箭头函数不使用上面的绑定规则,根据外层作用域来决定this,继承外层函数调用的this绑定。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
看看这个有着深不可测的魔力的
this
到底是个什么玩意儿 ~什么是this
在传统面向对象的语言中,比如Java,
this
关键字用来表示当前对象本身,或当前对象的一个实例,通过this
关键字可以获得当前对象的属性和调用方法。在JavaScript中,
this
似乎表现地略有不同,这也是让人“讨厌”的地方~ECMAScript规范中这样写:
MDN上这样写:
可以这样理解,在JavaScript中,
this
的指向是调用时决定的,而不是创建时决定的,这就会导致this
的指向会让人迷惑,简单来说,this
具有运行期绑定的特性。参考资料:this - JavaScript | MDN
来看看不同的情况五花八门的
this
吧~调用位置
首先需要理解调用位置,调用位置就是函数在代码中被调用的位置,而不是声明的位置。
通过分析调用栈(到达当前执行位置所调用的所有函数)可以找到调用位置。
当我们调用
baz()
时,它会以此调用baz()
→bar()
→foo()
。对于
foo()
:调用位置是在bar()
中。对于
bar()
:调用位置是在baz()
中。而对于
baz()
:调用位置是全局作用域中。可以看出,调用位置应该是当前正在执行的函数的前一个调用中。
全局上下文
在全局执行上下文中
this
都指代全局对象。this
等价于window
对象var
===this.
===winodw.
在浏览器里面
this
等价于window
对象,如果你声明一些全局变量,这些变量都会作为this的属性。函数上下文
在函数内部,
this
的值取决于函数被调用的方式。直接调用
this
指向全局变量。call()、apply()
this
指向绑定的对象上。可以看到,定义了一个
say
函数是用来输出name
、age
和job
,其中本身没有name
和age
属性,我们将这个函数绑定到person
这个对象上,输出了本属于person
的属性,说明此时this
是指向对象person
的。如果传入一个原始值(字符串、布尔或数字类型)来当做
this
的绑定对象, 这个原始值会被转换成它的对象形式(new String()
),这通常被称为“装箱”。call
和apply
从this
的绑定角度上来说是一样的,唯一不同的是它们的第二个参数。bind()
this
将永久地被绑定到了bind
的第一个参数。bind
和call
、apply
有些相似。箭头函数
所有的箭头函数都没有自己的
this
,都指向外层。关于箭头函数的争论一直都在,可以看看下面的几个链接:
ES6 箭头函数中的 this?你可能想多了(翻译)
关于箭头函数this的理解几乎完全是错误的 #150
MDN中对于箭头函数这一部分是这样描述的:
箭头函数常用语回调函数中,例如定时器中:
附上MDN关于箭头函数
this
的解释:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions#不绑定_this
作为对象的一个方法
this
指向调用函数的对象。这里有一个需要注意的地方。。。
发现
this
又指向全局变量了,这是为什么呢?还是那句话,
this
的指向得看函数调用时。作为一个构造函数
this
被绑定到正在构造的新对象。通过构造函数创建一个对象其实执行这样几个步骤:
所以
this
就是指向创建的这个对象上。作为一个DOM事件处理函数
this
指向触发事件的元素,也就是始事件处理程序所绑定到的DOM节点。HTML标签内联事件处理函数
this
指向所在的DOM元素jQuery的this
在许多情况下JQuery的
this
都指向DOM元素节点。总结
如果要判断一个函数的
this
绑定,就需要找到这个函数的直接调用位置。然后可以顺序按照下面四条规则来判断this
的绑定对象:new
调用:绑定到新创建的对象call
或apply
、bind
调用:绑定到指定的对象注意:箭头函数不使用上面的绑定规则,根据外层作用域来决定
this
,继承外层函数调用的this
绑定。The text was updated successfully, but these errors were encountered: