你不知道的JSthis全面解析
2.1 调用位置
在理解this的绑定之前要理解this调用位置:调用位置就是函数在代码中被调用的位置 说成人话就是要确定this调用所在的作用域
例子:
function baz(){
console.log(this); //这个this指向的就是函数baz
}
console.log(this); //这个this就是指向的window
2.2绑定规则
2.2.1默认绑定
例子:
function foo(){
console.log(this.a);
}
var a=2;
foo(); //这里返回的是2,
上面这个this.a实际上就是在函数作用域中找,然后找不到之后就跑到全局作用域中去找了。
function foo(){
"use strict"
console.log(this.a);
}
var a=2;
foo(); // 这里返回undefined
如果采用严格模式,就会返回undefined
2.2.2隐式绑定
function foo(){
console.log(this.a)
}
var obj={
a:2,
foo:foo
}
var a=10086;
var st=obj.foo;
st(); //这里返回10086
obj.foo(); //这里返回2
上面这段代码返回2,obj.foo()是通过obj对象去调用foo()函数,this是指向obj,在obj对象中找,再找不到就返回undefined。
st()是在window中找a也就是全局作用域下,this指向的是window,st()可以写为,window.st()
function foo(){
console.log(this.a);
}
var obj={
a:2,
foo:foo
}
var a=10086
var st=obj.foo
obj.foo(); //这里是在obj中调用的,this指向的是obj,隐式绑定
st(); //这里是在全局中调用的st(),this指向window,隐式绑定
foo(); //这里是在全局中调用的st(),this指向window,隐式绑定
2.2.3 显式绑定
通过call和apply方法来进行绑定
function foo(){
var a="this is foo"
console.log(this.a);
}
var obj={
a:2
}
var a=10086
foo.call(obj) //这里返回2,将this绑定给了obj
foo.call(window); //这里返回10086,将this绑定给了window
foo.call(foo); //这里返回undefined,虽然绑定给了foo,但是无法访问里面的a只能通过闭包来访问
1、硬绑定
function foo(){
console.log(this.a);
}
var obj={
a:2
}
var bar=function(){
foo.call(obj) //这里是硬绑定
}
bar();
setTimeout(bar,100)
bar.call(window); //硬绑定之后无法修改它的this值
硬绑定的典型应用场景就是创建一个包裹函数,负责接收参数并返回值
function foo(someth){
console.log(this.a,someth); //返回2,3
return this.a+someth //ret 2+3
}
var obj={
a:2
}
var bar=function(){
return foo.apply(obj,arguments);
}
var b=bar(3);
console.log(b); //返回5
2.2.4 new绑定
传统面向对象语言中,“构造函数”是类的一种特殊方法,使用new初始化类时会调用类中的构造函数。
JS中的new是操作符,和绝大多数面向对象语言的new则完全不同。被new操作符调用的函数实际上就是普通的函数,也不会被实例化一个类。
使用new操作符调用函数会发生以下操作:
1、创建(或者说构造)一个全新的对象。
2、这个新对象会被执行[[Prototype]]连接,也就是绑定在prototype上
3、这个新对象会绑定到函数中调用this
4、如果函数没有其他返回对象,new自动返回这个新对象
2.3优先级
默认绑定是绑定中优先级最低的
function foo(){
console.log(this.a);
}
var obj1={
a:2,
foo:foo
}
var obj2={
a:3,
foo:foo
}
obj1.foo(); //这里返回2
obj2.foo(); //这里返回3
obj1.foo.call(obj2); //这里返回3
obj2.foo.call(obj1); //这里返回2
显式绑定优先级更高,也就是说在判断是应当考虑可以存在的显式绑定
2.4绑定例外
2.4.1 被忽略的this
如果你把null或者undefined作为this的绑定对象传入call,apply或者bind,这些值在调用时会忽略,实际应用的是默认绑定规则
function foo(){
console.log(this.a);
}
var a=2
foo.call(null); //这里返回的是2