基本类型和引用类型

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

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

属性

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

var p = new Obj();
p.name = "huyuping";
console.log(p.name)//huyuping var 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);//20
console.log(result);//30

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

我们看下面一种情况

function addTen(num) {
num+=10;
return num;
}
var count = 20;
addTen(count);
console.log(count);//20
console.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);//undefined
var 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= undefined
2)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= undefined
2)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= undefined
2)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里面定义变量或函数

js 变量、作用域和内存问题的更多相关文章

  1. js 变量 作用域及内存

    由于Javascript是松散型的,所以其变量只是在特定时间用于保存特定值的一个名字而已,并不存在某个变量必须保存某种类型的值的规则,变量的值以及其数据类型都可以在脚本的声明周期内改变 一.基本类型与 ...

  2. 第一百零六节,JavaScript变量作用域及内存

    JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...

  3. [刘阳Java]_步步窥探JS变量作用域

    今天的这个文章题目名称甚是让人会突发异想.JS变量作用域是务必需要搞懂的,单从面试过程就会让面试者烧脑壳.所以,我们还是写一篇关于JS变量作用域的技术专题,让所有小伙伴能够借此文章去整理JS的基础学习 ...

  4. javaScript的闭包 js变量作用域

    js的闭包 js的变量作用域: var a=90; //定义一个全局变量 function test(){ a=123; //使用外层的 a变量 } test(); document.write(&q ...

  5. 浅谈javascript中变量作用域和内存(2)

    1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...

  6. 原型模式故事链(5)--JS变量作用域、作用域链、闭包

    上一章 JS执行上下文.变量提升.函数声明 传送门:https://segmentfault.com/a/11... 本次我们主要讲讲变量作用域和闭包变量作用域:顾名思义:变量起作用的范围.变量分为全 ...

  7. 解释JS变量作用域的范例

    JS的变量作用域只有两种:全局作用域与函数作用域. 用var声明的变量不能简单的说是属于函数作用域,应该是说属于其最近的作用域. var a = 10; function test(){ var a; ...

  8. 浅谈js变量作用域

    变量的作用域也是前端面试题常考的一个问题,掌握下面几个规律可以帮你更好的理解js的作用域. 1.作用域优先级遵循就近原则,函数内部的作用域优先级大于外部 var a=456; var b=111; f ...

  9. js变量作用域--变量提升

    1.JS作用域 在ES5中,js只有两种形式的作用域:全局作用域和函数作用域,在ES6中,新增了一个块级作用域(最近的大括号涵盖的范围),但是仅限于let方式申明的变量. 2.变量声明 var x; ...

  10. JS变量作用域与解构赋值

    用var变量是有作用域的 变量在函数内部声明时,那么该变量只属于整个函数体,函数外不可调用 当两个不同的函数里,使用了用一个相同的变量名,二者不互相影响,相互独立 遇到嵌套函数时,外部函数不可调用内部 ...

随机推荐

  1. makefile中伪目标的理解

    1. 我们知道Makefile中的语法是这样: target ... : prerequisites ... command - - 2. 假如编译两个文件可以这么写: a.o:a.c  gcc -c ...

  2. linux网络、性能相关命令

    netstat -tunpl #查看进程列表 top #查看系统资源统计 服务器速度测试 ping 123.57.92.9 -t 每一个被发送出的IP信息包都有一个TTL域,该域被设置为一个较高的数值 ...

  3. 罗培羽—C语言简单游戏编程教学

    编写许多软件都需要有菜单,那么如果我们使用tc之类的软件来编译程序的话,我们该怎么编写菜单呢?让我们一起来试试吧!第一步:简单例子       我们先来写个最简单的例子:#include<std ...

  4. Server SQL2008对文件的基础操作(1)

    1.一个文件的基本框架为:文件名.文件地址.文件大小.文件最大的大小.文件的增量(Filegrowth). 2.文件有mdf.ndf.ldf 三种文件的区别. 3.文件组可以进行文件的管理 FileG ...

  5. Numpy入门 - 数组排序

    本节主要讲解numpy数组的排序方法sort的应用,包括按升序排列和按降序排列. 一.按升序排列 import numpy as np arr = np.array([[3, 1, 2], [6, 4 ...

  6. pdo 封装增删改查类

    <?php/** * Class model * @package Core\lib */class model{    protected $pdo = null;      // 连接数据库 ...

  7. yii2.0中数据缓存之增删改查

    public function actionSss(){ /* * 获取到缓存 * 这里是获取的是根目录下 的common/main.php中的缓存类组件 * */ $cache=\Yii::$app ...

  8. 高质量PHP代码的50个实用技巧必备(上)

    1.不要使用相对路径 常常会看到: ? 1 require_once('../../lib/some_class.php'); 该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. ...

  9. OBS源码解析(1)main函数

    int main(int argc, char *argv[]){#ifndef _WIN32 signal(SIGPIPE, SIG_IGN);#endif #ifdef _WIN32 /*Open ...

  10. 运行期以索引获取tuple元素-C++11之2

    //运行期以索引获取tuple元素-C++11之2 //需支持C++11及以上标准的编译器,VS2017 15.5.x.CodeBlocks 16.01 gcc 7.2 //参见<深入应用C++ ...