js内存空间及this关键词详解

前言


理解js内存空间,对于我们理解很多题目大有帮助,特别是一些面试项目。例如下面这个题目:

var a = 20 ;
var b = a ;
b = 30 ;
// 这时a的值是多少?

var m = { a : 10 , b : 20}
var n = m ;
n.a = 15;
// 这时m.a的值是多少

很多朋友搞不清楚。
还有一个this方面的面试题目。大体如下:

 var a = 20;
    var haoroomsobj = {
        a: 10,
        c: this.a + 20,
        fn: function () {
            return this.a;
        }
    }

    console.log(haoroomsobj.c);
    console.log(haoroomsobj.fn());
var haoobj=haoroomsobj.fn;
console.log(haoobj())

大家看看上面会输出什么?下面我就和大家一起来剖析一下这两个问题。这两个问题涉及到js内存空间及this关键词的相关知识,通过普及这些知识,来顺便解释一下这两个题目。

js内存空间


前面我有文章解释过如何应对js页面中的[内存泄露],但是并没有解释js内存空间的一些基础知识。下面我们先来理一下一个概念。

栈与堆

变量对象与基础数据类型(例如:Undefined、Null、Boolean、Number、String)都放在栈(stack)里
引用数据类型,比如:对象,数组等一般都放在堆(heap)里

例如如下代码:

var a1 = 0;   // 变量对象
var a2 = 'this is string'; // 变量对象
var a3 = null; // 变量对象

var b = { m: 20 }; // 变量b存在于变量对象中也可以理解为栈,{m: 20} 作为对象存在于堆内存中
var c = [1, 2, 3]; // 变量c存在于变量对象中也可以理解为栈,[1, 2, 3] 作为对象存在于堆内存中

基础数据类型也可以理解为栈里的数据都是按值访问,我们可以直接操作保存在变量中的实际的值。但是在堆内存中,我们不能直接操作对象的堆内存空间。在操作堆里的对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用类型的值都是按引用访问的。我们可以地把引用理解为保存在变量对象中的一个地址,这个地址是和堆内存的值是相关联的。

那么上面的面试题目我们可以用如下图来解释:

this.png

因此a还是20


第二个题目:

aaa.png

复制之后是引用的复制。修改了堆里面的对象之后,n和m对应的是同一个对象,因此输出m.a会变成15

关于this


关于this的解释,我前面也有过一篇文章,虽然写了一点点东西,但是写的比较浅。下面我就详细介绍一下this
函数中的this是难点和重点,我今天主要讲讲函数中的this
我对函数调用总结了如下三点:

1、this的指向,是在函数被调用的时候确定的
2、函数调用时,看其是否被某个对象所拥有,假如被某个对象拥有,那么函数中的this,指向的是其拥有的对象。
例如:

haoroomsobj.fn()

fn()函数被haoroomsobj所拥有,那么fn里面的this,指向的是haoroomsobj
3、如果函数独立调用,那么该函数内部的this,则指向undefined。在非严格模式中,当this指向undefined时,它会被自动指向全局对象。
例如haoobj() 是独立调用,那么haoobj函数里面的this会指向undefined,在非严格模式下面指向的是全局对象。

通过上面的三条结论,我们对于函数的调用应该很清楚了,我们再来看下:

haoroomsobj.c

这个不是我们上面所说的函数情况,因此,还有一个结论:

当haoroomsobj 在全局声明时,无论haoroomsobj.c在什么地方调用,这里的this都指向全局对象,
而当haoroomsobj在函数环境中声明时,这个this指向undefined,在非严格模式下,会自动转向全局对象。

我们再来看下上面的题目吧:

console.log(haoroomsobj.c);
console.log(haoroomsobj.fn());
 var haoobj=haoroomsobj.fn;
console.log(haoobj())

通过上面的结论,我们可以解释:

console.log(haoroomsobj.c)


haoroomsob是全局声明haoroomsobj.c在非严格模式下面指向的是window全局对象,因此:

this.a + 20

输出40

console.log(haoroomsobj.fn());


fn()是haoroomsobj对象下面的函数,这里this指向的是haoroomsobj,因此输出的是10

console.log(haoobj())


haoobj()函数是独立调用,指向的是全局,因此输出20

小结


js内存空间,关键理清堆里面的数据,在操作堆里的对象时,实际上是在操作对象的引用而不是实际的对象

this关键词要理清函数调用,是独立调用还是被某个对象所调用。独立调用在非严格模式下面指向的是全局,被某个对象所调用,this指向的是某个对象!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容

  • 没搞错吧!js写了那么多年,this还是会搞错!没搞错,javascript就是回搞错! ………… 在写java的...
    zhoulujun阅读 1,430评论 0 11
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,710评论 2 17
  • 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上...
    web蜗牛阅读 576评论 1 4
  • 1,javascript 基础知识 Array对象 Array对象属性 Arrray对象方法 Date对象 Dat...
    Yuann阅读 887评论 0 1
  • 在线阅读 http://interview.poetries.top[http://interview.poetr...
    程序员poetry阅读 114,205评论 24 450