为什么要有this?
我们来看两串代码
这一串没有this辅助
js
const user1={name:'张三'}
function sayName1(){
console.log(user1.name)
}
const user2={name:'李四'}
function sayName2(){
console.log(user2.name)
}
sayName1()//张三
sayName2()//李四
这一串有this辅助
js
function sayName(){
console.log(this.name)
}
const user1={name:'张三'}
const user2={name:'李四'}
sayName.call(user1)//张三
sayName.call(user2)//李四
明明两串代码差不多长,为什么偏偏选择要用this呢
因为this是js当中的一个关键字,提供了一种更优雅的方式隐式地传递一个对象的引用,可以让代码更高效更简洁,易于复用
this能被用在哪?
有域的地方就有this,用在不同的地方,代指的东西不一样
- 全局
this出现在全局时 this===window
当this在node中被使用时,输出的是一个空对象
js
console.log(this)//{}
当this被浏览器调用时

- 函数体内
this的绑定规则
- 默认绑定:当函数独立调用时,函数中的
this指向window对象
js
var a=1 //===window:{a:1}
function foo() {
console.log(this.a)
}
function bar(){
var a=2
foo()
}
bar()//浏览器输出1,node输出undefined
当代码执行时,由于foo里面没有定义a,所以foo就会去window找a,所以输出1
- 隐式绑定:当一个函数被一个上下文对象所拥有,并被该对象调用,函数中的this指向该对象
js
function foo(){
console.log(this)
}
var obj={
a:1,
foo:foo
}
obj.foo()//{a:1,foo:f}
此时foo被obj调用,所以this指向obj,输出{a:1,foo:f}
- 隐式丢失:当一个函数被多层对象调用,函数的this指向最近的那个对象
js
function foo() {
console.log(this.a)
}
var obj = {
a: 1,
foo: foo
}
var oo = {
a: 2,
foo: obj
}
oo.foo.foo()//1,相当于执行obj.foo(),所以this指向的是obj
- 显示绑定:
- fn.call(obj,x,y)
js
function foo(x,y){
console.log(this.a,x+y)
}
var obj={
a:1
}
foo.call(obj,1,2,3)//1 3 将obj中的参数传入foo中执行,其余从前往后执行
foo//undefined NaN
- fn.apply(obj,[x,y]) ,xy是数组的最后两位
js
function foo(a,x,y){
console.log(this.a,x+y)
}
var obj={
a:1
}
foo.apply(obj,[1,2,3,4])//1 7 执行数组的最后两位,分别是3、4
- fn.bind(obj,x,y)()
js
function foo(a,x,y){
console.log(this.a,x+y)
}
var obj={
a:1
}
foo.bind(obj,1,2,3,4)(1,2)//1 5 返回的值是2,3,是从第二个参数开始执行的
foo.bind(obj,1)(1)//1 2 参数可以分开传递
小拓展之箭头函数
箭头函数没有this的概念,写在箭头函数中的this,也是它外层那个非箭头函数的this
js
var fn=()=>{
console.log(this.a)
}
var obj={
a:1,
fn:fn
}
obj.fn()//undefined
this挂载在全局上,相当于在全局输出a,执行时与obj无关,由于全局没有定义a,所以输出undefined
不能作为构造函数用
js
function foo(){
var fn=()=>{
this.a=1
}
fn()//相当于foo(){this.a=1}
}
var obj={
a:2,
bar:foo
}
obj.bar()
console.log(obj.a)//1