this 指向问题 一般情况下 this 的最终指向是那个调用它的对象。
①在全局作用域下或者普通函数中 this 指向全局对象window,包括定时器。
因为在全局作用域下,变量和函数都是window的属性或者方法,所以也就是说他们的调用者就是 window。
console.log(this)
function fun(){
console.log(this);
}
本质:
window.function fun(){
console.log(this);
}
setTimeout(function(){
console.log(this);
},1000);
本质:
window.setTimeout(function(){
console.log(this);
},1000);
②方法调用中:谁调用this就指向谁。
调用对象o
里面的方法
this
指向对象o
var o = {
sayHi:fuction(){
console.log(this);
//this 指向的是 o 这个对象
}
}
o.sayHI();
调用 btn
按钮对象
this
指向的是 btn
var bth = document.querySelector('button');
//传统注册事件方法
btn.onclick = function(){
console.log(this);
}
//事件监听
btn.addEventListener('click',function(){
console.log(this);
})
③构造函数中this指向构造函数中的实例。
在构造函数里调用this
指向的是 Fun
的实例对象 fun
function Fun(){
console.log(this);
}
var fun = new Fun();
独立函数调用都是指向 window
“ 独立的函数调用 ” 我们可以理解成:函数没有被绑定到某个对象进行调用。
window是它的绑定对象
function foo(){
console.log("foo:",this);
}
foo();
在 ②这种情况中 虽然函数定义在了对象里面,但还是被单独调用,所以此时this
的绑定对象 仍是 window
。
在 ①这种情况中 函数定义在了对象里面,而且是被对象调用的,所有此时this
的绑定对象是 object
。
所以 this 的绑定对象,与函数的声明位置没有关系。
var obj = {
name:"why",
bar:function(){
console.log("bar:",this)
}
}
① obj.bar()
//此时 this 指向的是 object
② var baz = obj.bar
baz();
// 此时 this 指向的是 window
this
指向都是undefined
一般打包工具会自动将js文件设置成 严格模式,这样可以规避一些低级错误。
"use stric"
function foo(){
console.log("foo:",this);
}
foo();
var obj = {
name:"why",
bar:function(){
console.log("bar:",this)
}
}
var baz = obj.bar
baz();
总结:
this
代替 window
会比较危险,所以建议直接window
来写。 window
的!function foo(){
console.log("foo:",window);
}
foo();
通过某个对象进行调用,即调用位置是某个对象发起的函数调用。
前提:必须在调用的对象内部有一个函数的引用,(比如一个属性)
简单来说就是:将函数赋值给了对象的某个属性,然后通过调用对象的这个属性的方式调用函数就是隐式绑定
function foo(){
console.log("foo函数:",this);
}
var obj = {
bar:foo
//将上面声明的那个 foo()函数 赋值给这个 bar 属性
}
obj.bar();
// 调用 obj 对象中的 bar 属性
与隐式绑定不同,显式绑定是通过call()等方法调用自己指定好的this指向的函数。
var obj = {
name:"why";
}
function foo(){
console.log("foo函数",this)
}
// 执行函数,并且强制 this 指向 obj 对象
foo.call(obj)
// 可以将 this 指定为 任意对象
foo.call("123")
foo.call(“abc”)
实现显式绑定的两个方法
function foo(name,age,height){
console.log("foo函数被调用",this);
console.log("打印参数",name,age,height);
}
语法:
foo.applay("apply",["shenqi",18,1.55]);
语法:
foo.call("call","shenqi",18,1.55);
总结:第一个函数是相同的,参数均为this所需要指定的对象,后面的参数,apply为数组,call为参数列表.
我们发现 如果我们想多次调用指定好this指向的函数时都需要调用 apply或者 call。
foo.applay();
foo.applay();
foo.applay();
foo.applay();
foo.applay();
foo.applay();
有没有什么方法可以一劳永逸呢?
bind 便应运而生。
bind本质是 根据调用函数与指定的obj对象生成了一个新的函数,使得指定的obj 对象总绑定在 新的函数上。
独立函数的优先级低的,所以一定是 先执行bind方法绑定之后独立函数才会被执行
var bar = foo.bind()
bar()
bar()
bar()
bar()
bar()
bind方法创建的新的绑定函数(EF)是一个怪异函数对象
JavaScript 中的函数可以当做一个类的构造函数来使用,也就是new关键字。
new 之后发生了什么?
function foo(){
this.name = "shenqi"
console.log("foo函数",this)
// 此时this 就是指向 默认创建的 全新的空对象
}
new foo()
有时候,我们会调用一些JavaScript的内置函数,或者一些第三方库中的内置函数。
需要依靠
this 指向:“abc”
this 指向 :“aaa”
this指向:“aaa”
this指向:一个空对象 和 false
this指向:一个空对象
总结:new>bind>call=apply>默认绑定。
注意:new和 call、apply是不允许一起使用的,没有可比性。
ok以上就是对 JS高级篇 |彻底搞清this指向问题 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。
coderwhy老师JS高级视频教程