专栏名称: hpoenixf
前端
目录
相关文章推荐
保险一哥  ·  2024年度34省市区保险状元来了!你们公司 ... ·  5 天前  
一条  ·  一个大厂员工的夜生活,被全网点赞 ·  4 天前  
一条  ·  中国最霸气的桥,端午必去 ·  6 天前  
51好读  ›  专栏  ›  hpoenixf

一次搞定闭包和this

hpoenixf  · 掘金  ·  · 2018-04-02 12:14

正文

请到「今天看啥」查看全文



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>

变量对象

变量对象是与执行上下文相关的数据作用域,存储了上下文中定义的变量和函数声明。







请到「今天看啥」查看全文