正文
function foo() {
this.a = 1
console.log( this.a );
}
function doFoo(fn) {
this.a = 4
fn();
}
var obj = {
a: 2,
foo: foo
};
var a =3
doFoo( obj.foo ); // 1
这是为什么呢?是因为优先读取foo中设置的a,类似作用域的原理吗?
通过打印foo和doFoo的this,可以知道,他们的this都是指向window的,他们的操作会修改window中的a的值。并不是优先读取foo中设置的a
因此如果把代码改成
function foo() {
setTimeout(() => this.a = 1,0)
console.log( this.a );
}
function doFoo(fn) {
this.a = 4
fn();
}
var obj = {
a: 2,
foo: foo
};
var a =3
doFoo( obj.foo ); // 4
setTimeout(obj.foo,0) // 1
上面的代码结果可以证实我们的猜测。
用new构造就指向新对象
a = 4
function A() {
this.a = 3
this.callA = function() {
console.log(this.a)
}
}
A() // 返回undefined, A().callA会报错。callA被保存在window上
var a = new A()
a.callA() // 3,callA在new A返回的对象里
apply/call/bind
function foo() {
console.log( this.a );
}
var obj = {
a: 2
};
foo.call( obj ); // 2
//bind返回一个新的函数
function foo(something) {
console.log( this.a, something );
return this.a + something;
}
var obj =
a: 2
};
var bar = foo.bind( obj );
var b = bar( 3 ); // 2 3
console.log( b ); // 5
箭头函数
箭头函数比较特殊,没有自己的this,它使用封闭执行上下文(函数或是global)的 this 值。
var x=11;
var obj={
x:22,
say:()=>{
console.log(this.x); //this指向window
}
}
obj.say();// 11
obj.say.call({x:13}) // 11
x = 14
obj.say() // 14
//对比一下
var obj2={
x:22,
say() {
console.log(this.x); //this指向window
}
}
obj2.say();// 22
obj2.say.call({x:13}) // 13
事件监听函数
指向被绑定的dom元素
document.body.addEventListener('click',function(){
console.log(this)
}
)
// 点击网页
// <body>...</body>
HTML
HTML标签的属性中是可能写JS的,这种情况下this指代该HTML元素。
<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
变量对象
变量对象是与执行上下文相关的数据作用域,存储了上下文中定义的变量和函数声明。