最近想写一点node的东西,一直无从下手,看了一些js的基本知识,却一直觉得掌握的很不好,有时候感觉能知道在说什么,但是等到自己用的时候,还是无从下手。今天自己研究一下js的上下文环境,也就是当下的this到底指代的什么。希望自己能够通过博客的形式将所看到的东西整理并二次消化一下。
本文的立场是希望看到文章的各位大神能对针对文中所述的相关问题或者知识阐述一下自己的理解,所以我会阐述我比较极端的理解,你喷我我不怕,就怕你不说话。
本文所描述的场景均不是在严格模式下
理解JavaScript的引用
对于java来说,引用非常好理解,就是在堆中存了一块东西,引用可以看做是一个简单类型,简单类型存储了地址(地址就是存的这块东西的位置)。多个对象都可以存相同的地址,看起来这几个对象就是相等的,其实是这几个对象存的地址相等(所以java所谓的都是值传递的说法就是指的copy了一份地址)。而对于对象的操作便是通过地址找到这块东西,再对这块东西进行操作,所以不同的对象会对让同一块东西发生改变。这个都是大家耳熟能详的知识,js的函数其实也是这样的。
我对以下言论不负责,都是我个人理解。js的函数分为两部分,声明和执行。声明其实在哪声明都一样,是否显示声明或者匿名也都一样(在我看来只有匿名声明一种,后面会提到)。接下去便是js函数的执行了,执行的话其实就是函数后面跟上(),这个的话正如上面说的引用,不管是在哪的变量是函数的引用,后面加上()就执行了该函数。
高能预警!!!
当前引用该函数的对象在哪个位置?很关键!当前这个对象到底属于哪个对象下面?
举个栗子
//声明一个函数
function test(){
console.log(this);
};
等同于
var test = function(){
console.log(this);
};
/* test就是属性(变量),目前内存中有一个方法,test就是指向该方法的属性。
!!!我要说一句不负责任的话,把方法都当成是匿名的,各种XXX()中的XXX都
是对于该方法的引用,就是我上面说的等同于。
这个地方有人要质疑我,其实就是匿名的,只不过,function有个叫name的属性。
*/
//这种情况test1()在test1函数外部是无法被调用的,undefined;
var test=function test1(){
test1();//true
}
test1();//false
//全局执行,test是window对象里面的一个属性,所以this指window。
test();
/* 这个时候haha是该function的引用,而haha是hello对象下的一个属性,
所以this指的是hello这个对象。
*/
var hello = {
haha : test
}
hello.haha();
function Diaosi(name) {
this.name = name;
console.log(this);
}
//http://blog.youkuaiyun.com/fibonacii/article/details/53360107#3构造器调用模式
/* 可以查看我的另一篇博客,了解构造器的形式到底在干吗,这边简单说一下,
就是创建了一个新的对象,可以同java一样理解,this便是该新对象。
*/
var d = new Diaosi('yuanchen');
//直接调用是有区别的,Diaosi就是在window下的属性的执行,返回指赋值给d1,这段代码里会是undefined
var d1=Diaosi('yuanchen');
ES6中新定义的语法中的箭头函数,箭头函数中的 this 只和定义它时候的作用域的 this 有关,而与在哪里以及如何调用它无关,同时它的 this 指向是不可改变的