this一直有点晕,今天写了一个测试,但是还是不理解,求高手给个通俗易懂的简答:
以下代码,为什么点击按钮执行函数内部创建的函数this指向的事window?
(function(){
console.log(self);
console.log(this);//这里的this指向window
})();
<body>
<button id="di" >ssss</button>
<script type="text/javascript">
var d=document.getElementById('di');
function a(){
name='111'
console.log(this);
}
d.addEventListener('click',function(){
a();//a打印的this是window
console.log(this);//打印的是d对应的button元素
var self=this;、//保存this
//为什么内部创建的函数this指向window
(function(){
console.log(self);
console.log(this);//这里的this指向window
})();
});
</script>
</body>
</html>
d.addEventListener('click',function(){
a();//a打印的this是window
你这么调用a不就相当于window.a(),this肯定是window啊
console.log(this);//打印的是d对应的button元素
这个this和当前dom元素绑定的处理函数有关,应该是addEventListener方法绑定事件的时候给callback函数的this绑定d元素吧。这个你可以查查资料是不是。
var self=this;//保存this
//为什么内部创建的函数this指向window
(function(){
console.log(self);
这里self是你这个匿名函数的父作用域的self,就是父作用域的this,和上一句一样。
console.log(this);//这里的this指向window
这个匿名函数不就和a函数一样吗?
换种写法:
function test(){
console.log(this);
}
test() === window.test();
})();
});
在闭包中使用 this 对象也可能会导致一些问题。我们知道, this 对象是在运行时基于函数的执行环境绑定的:在全局函数中, this 等于 window,而当函数被作为某个对象的方法调用时, this 等于那个对象。不过,匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window。但有时候由于编写闭包的方式不同,这一点可能不会那么明显。 --摘自JavasSript高级程序设计
从上面的话我个人理解分出三种情况。
全局函数调用,this指向window
匿名函数调用,this指向window
函数作为某个属性对象调用,此时this指向那个对象。例如执行a.func(); 此时this指向a。如果是a.b.func()。此时this指向a.b。
其实我个人觉得还有一种情况就是局部函数被调用。例如
function outer(){
function inner(){
console.log(this);
}
inner();
}
outer();// this 指向windows
此时this也是指向 windows。
你这里是属于 匿名函数调用所以this指向window。 至于为什么你的click回调函数this指向Button我个人理解这里是属于约定吧。
以上是我个人理解,欢迎各位大神指正我呀。
js中,匿名函数的this指向全局作用域
简单点说this是指向函数的调用者,foo.bar()这样的,this就是foo
bar()的话,就没有调用者,this就会指向window
任何地方以:
function a() {
console.log(this);
}
的形式定义函数,此函数都会被加到顶级对象中(浏览器中是 window
)
匿名函数也是如此。
至于为什么有个 this
指向对应的元素,是因为 addEventListener
就是这样实现的。自己也可以实现,参考文档 func.apply()
或 func.call()
和 func.bind()
我理解的 Javascript中this的含义是:调用包含this的函数的那个对象,
第一种情况,全局对象window调用的函数中的this
alert(this)//window
function fooCoder(x) {
this.x = x;
}
fooCoder(2);
alert(x);// 全局变量x值为2
第二种情况,构造函数中的this(之前见过许多次)
function Person(name){
this.name = name;
};
var tom = new Person("tom");
这里的this 指向的是通过构造函数 new 出来的那个tom对象。因为tom调用了 this所在的Person函数。
第四种情况,对象的方法中调用的this
Person.prototype.say = function (){
console.log(this.name +" say hello~");
}
这里的this 指向的是调用这个方法的对象。例如tom.say(),这时this指向的是tom。原理同上
这种是在全局作用域中调用了包含了this的那个alert函数,所以这时this是指全局作用域,即window。
对于浏览器的三种添加事件监听的方式this也有不同。
第一种:直接在标签内写 onclick=“fn”
第二种:在js中 onclick=fn
第三种:在js中 用el.attachEvent或者el.addEventListener()
三种方式添加的事件处理函数运行的scope是不同的,不同浏览器也不尽相同。
IE
js: el.onclick = fn ,fn的this->el
在标签中 onclick = "fn()" ,fn的this->window
js: el.attachEvent('onclick',fn); ,fn的this->window
Firefox、Chrome、Opera
js: el.onclick = fn ,fn的this->el
在标签中 onclick = "fn()" ,fn的this->window
js: el.addEventListener('onclick',fn); ,fn的this->el
我之前也纠结过这个问题,后来查找犀牛书才发现其实很好判断。
1.当函数作为函数(包括匿名函数)调用时,在严格模式下,this为undefined,非严格模式下,this统统指向window
2.当函数作为方法调用时,this指向调用它的那个对象
3.在call、applay用法中,this指向设定的上下文
因为function a的定义在全局,它的作用域链直接就是globle,所以this是指向window的呀.