我们知道js中有个全局对象就是window
,如果在顶层声明一个变量如
var a=1 //就相当于window.a=1
同时有了node以后,js也可以在服务端运行了,官方解释为Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。通俗说node是一个支持js语法的容器,直接写js就可以在node下运行。这里介绍node主要说一下在node中的全局变量叫global
,就像window
一样有一些js默认的变量和方法。下面只探讨this
在浏览器中的指向,有兴趣的也可以把后面的例子在node中跑一下。
this一般在函数中使用比较多,那就从函数说起吧,我们调用的函数一般分为声明式函数,或者是放在对象中作为方法的函数
一、声明式
function demo1(){
console.log(this)
}
function demo2(){
this.num=2
function demo3(){
this.num++
console.log(num)
}
return demo3
}
demo1() // 调用demo1函数,这里this很显然指向window
var a=demo2();
a() // 这里看到会打印出3,应该也很好理解,a变量将demo2函数执行后的的返回值及demo3函数返回,然后执行,此时this依旧指向window
二、对象中的方法调用
var obj1={
value:3,
increment:function(){
this.value++;
console.log(this,this.value)
}
}
obj1.increment() // obj1{value:4,increment:function(){...}},4 ;打印出obj1对象和4,obj1包含一个value值和一个increment方法,也好理解
在看一个例子
var obj2={
value:4,
increment:function(){
this.value++;
console.log(this,this.value);
(function(){
console.log('这又是啥',this,this.value)
this.value=1
})()
},
print:function(){
console.log('print',this.value)
}
}
obj2.increment()
obj2.print()
var P=obj2.print
P()
// 打印结果出如下
// {value: 5, increment: ƒ, print: ƒ}
// 5
// 这又是啥 Window
// undefined
// print 5
// print 1
依次分析:
第一条先执行obj2中的increment方法,跟上一个例子一样,这里的this是指向我obj2对象,所以this.value再执行+1以后为5,后面是一个自执行函数,这里面的this直接指向了window,window的value一开始不存在所以为undefined,后面增加一个全局变量value值为1;然后是第二条直接执行obj2中的方法print,此时的this还是obj2所以值为5,;然后是第三条声明一个变量P指向obj2中的print方法,执行这个方法这是this指向window,所以输出1
总结来说:
使用声明式函数(后面两个对象中的方法也是使用的声明式函数)会自动绑定this
,直接在全局中声明的函数this
会直接指向window
对象
延伸一下,现在我们都经常会用的es6的箭头函数,箭头函数是不会自动绑定this
的,默认从上一级继承下来,那不妨把刚才的例子改下看看
例子1改写
var demo1=()=>{
console.log(this)
}
var demo2=()=>{
this.num=2
function demo3(){
this.num++
console.log(num)
}
return demo3
}
demo1() // 调用demo1函数,这里this还是指向window,因为之前说的在全局下声明本身就有个this指向window对象
var a=demo2();
a() // 3,这里也一样
例子2改写
var obj1={
value:3,
increment:()=>{
this.value++;
console.log(this,this.value)
}
}
obj1.increment() // 这时候会看到输出window对象和一个NaN
简单说明下:
如前面所说箭头函数不会自动绑定this
,所以执行increment函数中的this
依旧会指向window
,而window
下的value
还不存在,所以为undefined
再执行+1操作所以value
就变成了NaN
了
例子3改写
var obj2={
value:4,
increment:()=>{
this.value++;
console.log(this,this.value);
(function(){
console.log('这又是啥',this,this.value)
this.value=1
})()
},
print:()=>{
console.log('print',this.value)
}
}
obj2.increment()
obj2.print()
var P=obj2.print
P()
// 打印结果出如下
// Window
// NaN
// 这又是啥 Window
// NaN
// print 1
// print 1
简单说明下:
第一个依旧window
对象,后面的value当然又是没声明.....然后自执行函数也没得说,后面才接着给window
的value
赋值为1了,后面就两句自然输出两次1了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。