先理解两个概念:基本类型和引用类型的值

1、基本类型和引用类型的值

(1)定义:

基本类型:指简单的数据段,比如按值访问的js五种基本数据类型undefined、null、boolean、number、srtring

引用类型的值:指保存在内存中的对象,注意一点,js不允许直接操作对象的空间

(2)相似和区别:

     相同:定义两种类型的方式都类似:创建一个变量并赋值

     不同点1:对于引用数据的值,我们可以添加属性进去,但是基本类型不行,强行添加会报undefined

  下面给个例子:

  var person = new Object()
  person.name = "saebr";
  console.log(person.name)//saber

  而基本类型添加属性会报undefined:

  var name = "saber";
  name.sex = "女";
  console.log(name.sex)//undefined

    不同点2:变量的复制也不相同:

  var num = 777;
  var num1 = num;
  console.log(num1)//

  基本类型的复制,简单来说就是用num的值来初始化num1,num1中也保存了值777,但是num和num1保存的777是两个完全独立的。

  var obj = new Object();
  var obj1 = obj;
  obj.name = "saber";
  console.log(obj1.name)//saber

  而引用类型的复制,最简单的话来说就是obj保存了一个对象的新实例,复制的过程就是让obj1的指针也指向这个对象,因此改变其中一个变量就会影响到另外一个变量。

    不同点3:参数传递的不同

  传递基本类型的值时,被传递的值会被复制给一个局部变量,而传递引用类型的值时,会把值得内存的地址复制给局部变量,这么说可能不好理解,撸两个例子看看:

  首先是基本类型的传递参数:

  function add(num) {
   num += 1;
  return num;
  }
  var saber = 7;
  var archer = add(saber);
  console.log(saber)//
  console.log(archer)//

  使用数值等基本类型来传参,函数内部的不会影响外部saber的变量,因为num和saber互相不认识,他们仅仅有相同的值,也就是如同上面所说的是完全独立的。

  其次是引用类型的传递参数:

  var person  = new Object();
  function setName(obj){
   obj.name = "saber"
  };
  setName(person);
  console.log(person.name)//saber

  看上去好像引用类型的传递参数是按引用传递,第一次看上去好像是这么回事,在局部作用域里面修改对象,会在全局作用域里展现出来,所以误认为是按引用传递。

  实际上js都是按值来传递参数的,上面的基本类型就不说了,简单明了,下面写个例子证明一下,引用类型是按值传递的:

  var person  = new Object();
  function setName(obj){
   obj.name = "saber"
   obj = new Object();
   obj.name = "archer"
  };
  setName(person);
  console.log(person.name)//saber

也就是说如果是按引用传递的话,person会被修改为指向name属性值为archer的新对象,但是结果是saber,这已经说明了一切。事实上,当函数执行完毕,这个archer的局部对象会被立即销毁。

(3)检测引用类型

检测基本数据类型使用typeof,那么如何检测引用类型呢?

所有引用类型的值都是Object的实例,escript提供了instanceof来检测引用类型和Object构造函数,如果是的话,返回true;

2、作用域

首先,要了解一个概念,全局执行环境被认为是windows对象,然后,每个函数都有自己的执行环境,当执行流进入一个函数时,这个函数的环境就会被推入一个环境栈中,当执行完,就会退出这个环境栈,然后返回之前的执行环境

作用域链

所以,当代码在一个环境中执行时,就会创建一个对象的作用域链。简单说一下作用域链,作用域链的下一个变量对象来自于外部环境,再下一个变量对象又来自更外一层的环境,这样一层一层直到最外层的全局执行环境windows。

还是撸一串代码看看,光说根本一连懵逼呀:

var SName = "saber";
function changeSavant(){
var AName = "archer";
// console.log(SName)//saber
// console.log(AName)//archer这里可以访问两个,访问不了beateSavant里面的LName
beateSavant();
function beateSavant(){
var LName = AName;
AName = SName;
SName = LName;
console.log(SName)//archer
console.log(AName)//saber
console.log(LName)//archer这里三个都可以访问到
}
}
// console.log(SName)//saber这个地方只能访问到SName
// console.log(AName)//AName is not defined
changeSavant();

简单来说,可以看到,函数内部的可以访问到外部的,但是外部的无法访问到内部的变量,那么这是如何访问到的呢,所以这就是作用域链的作用,首先函数的局部环境会先在自己的环境中搜索变量和函数名,搜索不到就再搜索上一层的作用域链。

这下是不是简单明了了很多~

延长作用域链

js有两种方式来延长作用域链:

(1)try catch中的catch

function add() {
try{}
catch{}//延长的作用域链
}

(2)with

浅谈javascript中变量作用域和内存(1)的更多相关文章

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

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

  2. 浅谈javascript中的作用域

    首先说明一下:Js中的作用域不同于其他语言的作用域,要特别注意     JS中作用域的概念: 表示变量或函数起作用的区域,指代了它们在什么样的上下文中执行,亦即上下文执行环境.Javascript的作 ...

  3. 浅谈javascript的变量作用域

    1.变量遵循先声明再使用. console.log(b); b=123; 代码运行结果: Uncaught ReferenceError: b is not defined 2.方法内定义的局部变量外 ...

  4. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  5. 浅谈JavaScript中的null和undefined

    浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...

  6. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  7. 浅谈JavaScript中的变量、参数、作用域和作用域链

    基本类型和引用类型 在JavaScript中有两种数据类型值.基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值指的是可能由多个值构成的对象.在JavaScript中有5种基本数据类型 ...

  8. 浅谈JavaScript中的内存管理

    一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...

  9. 浅谈JavaScript中闭包

    引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...

随机推荐

  1. @ServeletComponentScan和@ComponentScan的区别

    一.SpringBoot中使用Servlet在SpringBootApplication上使用@ServletComponentScan注解后,Servlet.Filter.Listener可以直接通 ...

  2. QVector init error

    QMetaType::registerType: Binary compatibility break -- Size mismatch for type 'PtsData' [1025]. Prev ...

  3. osg编译日志

    1>------ 已启动全部重新生成: 项目: ZERO_CHECK, 配置: Debug x64 ------1> Checking Build System1> CMake do ...

  4. 123457123456#0#----com.tym.ErTongFanPai20--前拼后广--儿童FanPai_tym

    com.tym.ErTongFanPai20--前拼后广--儿童FanPai_tym

  5. LeetCode_219. Contains Duplicate II

    219. Contains Duplicate II Easy Given an array of integers and an integer k, find out whether there ...

  6. Ubuntu18安装虚拟机virtualbox

    环境查看 安装虚拟机 apt install virtualbox 图形化界面启动 virtualbox 其余创建虚拟机和安装和在Windows安装配置一样,不详述.

  7. didSelectRowAtIndexPath方法无响应解决办法

    tableview的代理事件didSelectRowAtIndexPath失效,可能有三个原因: 1.没有设置tableview的Delegate  需要设置tableview的代理才可以响应代理事件 ...

  8. python实践项目一:Collatz函数

    要求1:编写一个名为 collatz()的函数,它有一个名为 number 的参数.如果参数是偶数,那么 collatz()就打印出 number // 2, 并返回该值.如果 number 是奇数, ...

  9. Angular 发布订阅模式实现不同组件之间通讯

    在我们项目中要实现不同组件之间通讯,Angular的@Input和@Output只能实现有父子组件的限制,如果是复杂跨组件实现不同组件可以通过共享变量的方式实现,比如这个博客的思路:https://w ...

  10. linux软件安装习惯

    Linux 的软件安装目录是也是有讲究的,理解这一点,在对系统管理是有益的 /usr:系统级的目录,可以理解为C:/Windows/,/usr/lib理解为C:/Windows/System32./u ...