this
在js中一直是谜同样的存在着,在面试中也是常常会被问道,接下来总结下我所理解的this
。
首先引入秘密花园中对this的工做原理,文中指出有五种状况,分别是:javascript
this; //在全局范围内使用`this`,它将会指向全局对象复制代码
foo(); //this指向全局对象复制代码
test.foo(); //this指向test对象复制代码
new foo(); //函数与new一块使用即构造函数,this指向新建立的对象复制代码
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); //this被设置成bar
foo.call(bar, 1, 2, 3); //this被设置成bar复制代码
有这样一道题java
var obj = {
func: function(){
console.log(this);
}
}
var foo = obj.func;
obj.func() //this是obj
foo() //this是window复制代码
解释函数结果为何不同?git
这道题能够从函数调用来理解,从我看到的博文中有这样的解释,秘密花园中的函数调用,方法调用,显式的设置this都属于函数调用,至关于函数调用的三种方式,能够写成github
foo(params);
obj.child.foo(params);
foo.call(context, params); //apply同理复制代码
并且前两种均可以写成第三种形式面试
foo(params); =>> foo.call(undefined, params);
obj.child.foo(); =>> obj.child.foo.call(obj.child, params);复制代码
因此说函数调用都是foo.call(context, params)
的变体,即函数调用只有一种。这样this
的值就是文中的context
,this
就是你函数调用时传入的context
。浏览器
举例代码中:app
function foo() {
console.log(this);
}
foo();复制代码
当你没法确认this
指代的值时,转化成call
形式会更好理解ide
function foo() {
console.log(this);
}
foo.call(undefined); //or foo.call();复制代码
函数执行结果为window
,在浏览器中有一条规定,传入context
为null
或undefined
时,则为全局对象(window对象);严格模式下context
为undefined
。函数
举例代码中:ui
var obj = {
func: function foo() {
console.log(this);
}
}
obj.foo();复制代码
转化为call
形式为
var obj = {
func: function foo() {
console.log(this);
}
}
obj.foo.call(obj);复制代码
很明显,this
指代obj。
btn.addEventListener('click' ,function handler(){
console.log(this) // 请问这里的 this 是什么
})复制代码
handler 中的this
是什么?用上面的方法好像无法转化了,由于不知道addEventListener
内源码实现,查看文档MDN
一般来讲this的值是触发事件的元素的引用,这种特性在多个类似的元素使用同一个通用事件监听器时很是让人满意。
当使用 addEventListener() 为一个元素注册事件的时候,句柄里的 this 值是该元素的引用。其与传递给句柄的 event 参数的 currentTarget 属性的值同样。
因此能够假设浏览器addEventListener是这样实现的
// 当事件被触发时
handler.call(event.currentTarget, event) // this => event.currentTarget复制代码
以上就是对this
的理解,若有错误请狠拍砖。