博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js 变量、作用域和内存问题
阅读量:5292 次
发布时间:2019-06-14

本文共 2670 字,大约阅读时间需要 8 分钟。

基本类型和引用类型

  • 5种基本类型:undefined、null、boolean、number、string

  • 引用类型:由多个值构成的对象

属性

引用类型可以动态添加属性,而基本类型不可以

var p = new Obj();p.name = "huyuping";console.log(p.name)//huyupingvar a;a.name = "huyuping";console.log(a,name)//出错

复制变量值

  • 基本类型

会在变量的对象上创建了一个新值,然后把复制到新变量分配的位置上。

下面的我形象化的帮助大家理解

这就相当于a和b都有一个房子,a把值复制给b后,b的房子了也有了这个值。

  • 引用类型

当从一个变量向另一个变量复制引用类型的值时,同时也会将存储在变量类型中的复制一份放到为新变量分配的内存空间中。

这可以这样理解:a,b都有自己的地方,a的值时放在另一个屋子里的,a复制给b,那a和b都要在哪个房子里去拿值,这个房子就是给a分配的内存,b的内存也指向哪个位置。

传递参数

  • 基本类型
    在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数)。
unction addTen(num) {    num+=10;    return num;}var count = 20;var result = addTen(count);console.log(count);//20console.log(result);//30

这里函数有个局部变量num,在使用之后就被回收了,然后函数返回一个值。

我们看下面一种情况

function addTen(num) {    num+=10;    return num;}var count = 20;addTen(count);console.log(count);//20console.log(addTen(count));//30

这次,我们没有定义result变量,而是直接输出addTen(count),输出的值还是30,这更说明了num时局部变量,不会影响count的值。

  • 引用类型
    在向参数传递引用类型的值时,会把这个值在内存中的地址复制给局部变量,因此这个局部变量的变化会反映在函数外部。
function setName(obj) {    obj.name = "huyuping";}var person = new Object();setName(person);console.log(person.name);//huyuping

在这个函数内部,obj和person引用的时同一个对象,所以为obj添加name属性的时候,在外面也有反应。

作用域

  1. script:全局变量、全局函数
  2. 函数:自上而下、由里到外

e.g.1

alert(a);//undefinedvar a = 1;function fn1 () {    alert(a);//undefined        var a = 3;}    fn1();    alert(a);//1

分析:

1.预解析:

1)a= undefined 2)fn1 = function fn1 () {alert(a);var a = 3; }(函数里的a是新定义的,所以预解析的时候会先是var a = undefined)

2.表达式:

1)a=1;2)调用函数         1.预解析 a= undefined         2.表达式 a=3

e.g.2

alert(a);//undefined        var a = 1;        function fn1 () {            alert(a);//1            a = 3;        }        fn1();        alert(a);//2

分析:

1.预解析:

1)a= undefined2)fn1 = function fn1 () {alert(a);var a = 3; }

2.逐行解读代码:

1)a=1;2)调用函数        1.预解析 (没有预解析,此时返回父级作用域(从子级作用域返回到父级作用域的过程叫作用域链)) 找到a=1,改为a=2

e.g.3

alert(a);//undefined        var a = 1;        function fn1 (a) {            alert(a);//undefined            a = 3;        }        fn1();        alert(a);//1

分析:

1.预解析:

1)a= undefined2)fn1 = function fn1 (a) {alert(a);var a = 3; }

2.逐行解读代码:

1)a=1;2)调用函数      1.预解析        function fn1 (a) a相当与var a                              a=undefined     2.逐行解读代码      a=3

e.g.4

var a = 1;        function fn1 (a) {            alert(a);//1            a = 3;        }        fn1(a);        alert(a);//1

分析:

1.预解析:

1)a= undefined2)fn1 = function fn1 (a) {alert(a);var a = 3; }

2.逐行解读代码:

1)a=1;2)调用函数    1.预解析  function fn1 (a) a相当与var a                              因为fn1(a),相当于对a传了参数,所以function fn1 (a)相当于function fn1 (var a = 1)    2.逐行解读代码                               a=3

if、for 是通透的不是作用域

注意:火狐解析不到if语句里面包着的函数体,所以尽量不要向if、for里面定义变量或函数

转载于:https://www.cnblogs.com/huyuzhu/p/6601552.html

你可能感兴趣的文章
Sqli labs系列-less-4 这关好坑!!!
查看>>
路由跟踪工具0trace
查看>>
给大家分享一张CSS选择器优选级图谱 !
查看>>
Win7中不能调试windows service
查看>>
T-SQL触发器,限制一次只能删除一条数据
查看>>
boost库使用:vs2013下boost::container::vector编译出错解决
查看>>
通过httplib2 探索的学习的最佳方式
查看>>
理解运算符重载 4
查看>>
快来熟练使用 Mac 编程
查看>>
第二周
查看>>
断言简介
查看>>
Node.js 入门:Express + Mongoose 基础使用
查看>>
plsql使用,为什么可以能看见其他用户的表
查看>>
一步步教你轻松学奇异值分解SVD降维算法
查看>>
Scripting Java #3:Groovy与invokedynamic
查看>>
2014-04-21-阿里巴巴暑期实习-后台研发-二面经验
查看>>
数据结构中线性表的基本操作-合并两个线性表-依照元素升序排列
查看>>
使用pager进行分页
查看>>
吐医疗器械研发可配置性需求的槽点
查看>>
UVA - 1592 Database
查看>>