阅读 732

老湿说的万物皆对象,你也信? | 重学JS

前言

  • 在线音乐戳我呀!
  • 音乐博客源码上线啦!
  • 浑浑噩噩在前端领域磕磕碰碰了两年多,想看看Vue源码,不知道有没有最近想看源码的猿友,如果JS不够硬,建议跟我一起来重学JS,重学完相信再去看源码,会事半功倍。
  • 接下来我们来看看JS的数据、变量、内存知识点都可以考些什么。

面试官:请问你最大的缺点是什么?
缺钱!
你被录用了!
这个新技能我get到了,下次可以试试。

先来回答:万物皆对象?

大学上课的时候,老湿一上来就给在座的各位单身狗说:万物皆对象。

当时就惊喜万分说:那如何拥有对象?

new出来。

年少不懂事,如今今非昔比,那么万物皆对象真的是对的吗?

通过上一篇数据类型之面试官(0101)我们得知,数据分为基本类型和引用类型,那么基本类型也属于对象吗?

很明显不是,所以我想说万物皆数据才是吧!!!

先来问自己三个面试题

var a = xxx, a内存中到底保存的是什么?

在JS调用函数时传递变量参数时, 是值传递还是引用传递?

JS引擎如何管理内存?

如果会了,面试官根本不是你的对手。
如果不会,我们先来理解数据、内存、变量之间的三角恋情。
只有知道问题背后的原理知识,解题必然随手拈来。

数据数据,那么什么是数据?

概念

存储在内存中代表特定信息的'信息', 其本质上是0101...

特点

可传递性、可运算性。

内存中所有操作的目标也正是:数据

  • 数据
    • 算术运算
    • 逻辑运算
    • 赋值
    • 运行函数

以上操作都将会产生数据。

内存:魂斗罗打击用的内存条?

内存条.png

内存和内存条两者可否关联?

概念

内存条通电后产生的可储存数据的空间(临时的)

内存生命周期

graph TD
内存条-电路版__    --> 通电__  --> 产生内存空间__  --> 存储数据__  --> 处理数据__  --> 断电__  -->内存空间和数据都消失__

内存空间和数据都消失,数据怎么会消失的?

空间没了,数据自然也跟着消失。因为数据就是在空间里面的。

就像宇宙大爆炸,我们还能存在嘛,是不是已经undefined了。

一块小内存上有2种数据类型

  • 内部存储的数据
  • 地址值

触碰到你的知识盲区?

问题不大,来张图。

1. 栈堆.png

现在从栈中,新建个var a = obj,那么我是将obj的内存赋给a吗?

不是的,是将obj的地址值拷贝给a。

那么对应上面的

  • 内部存储的数据 -- 对应的是obj
  • 地址值 -- obj对应的0X123

内存分为两种

  • 栈: 全局变量/局部变量
  • 堆: 对象
function fn(){
    // obj是局部变量,同时也是栈
    // { name } 该对象是堆空间
    var obj = { name: '吖泽' }
}
复制代码

函数是在堆,函数名是在栈中。

巴啦啦变变变,什么是变量?

顾名思义,可变化的量, 由变量名和变量值组成。

每个变量都对应的一块小内存, 变量名用来查找对应的内存, 变量值就是内存中保存的数据。

数据、内存、 变量三角恋关系?

内存用来存储数据的空间。

变量是内存的标识。

3. 数据、内存、 变量三角恋关系.png

相信看到这里对数据、内存、变量三者概念有了一定的了解了。

面试官:出道题给你热下身哈 ~

var obj1 = { name: '阿泽' }

var obj2 = obj1

请问:obj2保存的是什么,obj1的地址值吗?

NO ~ NO ~ NO ~

obj2保存的是obj1的内存内容,只不过这个内存内容恰巧是地址值;
但不能直接说:保存的是就是地址值。
复制代码

面试官:以下程序输出什么?99%的人都做错,不信你可以捂住答案 ^_^

  var a = {age: 12}
  var b = a
  a = {name: 'BOB', age: 13}
  b.age = 14
  console.log(b.age, a.name, a.age) 

  function fn2 (obj) {
    obj = {age: 15}
  }
  fn2(a)

  console.log(a.age)
复制代码

想好了答案,往浏览器输出一下,答案自然浮出水面(看看和自己的答案对上了没^_^)

关于引用变量赋值问题

了解上面的程序所挖掘的考点,其实是引用变量赋值的问题。

有两小点,其一:

(n)2个引用变量指向同一个对象, 通过一个变量修改对象内部数据, 另一个变量看到的是修改之后的数据

让我们通过程序翻译一下以上文字。

  var obj1 = {name: 'Tom'}
  var obj2 = obj1
  obj2.age = 12
  console.log(obj1.age)  // 12
  function fn (obj) {
    obj.name = 'A'
  }
  fn(obj1)
  console.log(obj2.name) //A
  
  // obj1、obj2两个或两个以上的引用变量指向同一个对象({name: 'Tom'});
  // 通过obj2.age = 12修改对象数据,那obj1自然也看到的是修改之后的数据。
复制代码

其二:(n)2个引用变量指向同一个对象, 让其中一个引用变量指向另一个对象, 另一引用变量依然指向前一个对象

同样,我们通过程序翻译一下以上文字。(其实就是上头那道编程输出题)

  var a = {age: 12}
  var b = a
  a = {name: 'BOB', age: 13}
  b.age = 14
  console.log(b.age, a.name, a.age)  // 14 Bob 13
  
  // a、b这2个引用变量指向同一个对象({age: 12}),
  // 让a重新赋值{name: 'BOB', age: 13},此时b指向的仍然是最初的{age: 12}
  // 现在a、b指向的就是两个对象了,因为a重新赋值啦。

  function fn2 (obj) {
    obj = {age: 15}
  }
  fn2(a)

  console.log(a.age) // 13
  
  // 应该最后一个输出,很多人的答案是15吧,为什么不是15呢?
  // 因为这是在fn2函数作用域内重新赋值,此次赋值是局部中,
  // 一旦fn2()函数执行完,函数本身会被释放,那{ age: 15 }就灰飞烟灭
  // 所以最终执行完,打印a.age还是13。
复制代码

函数执行完成,函数内的局部变量就会被释放。

思考:fn2()和上方其一讲的例子的fn()区别

这和上方的fn()可不一样,fn()里是obj.name可不一样,人家那是点链操作,还是改的是同一个对象。

fn()是修改属性,作用在全局环境中;

而fn2()是改引用对象的值,作用在局部环境中。

还是懵懵懂懂嘛,上张图助你更加清晰 ~ 仔细看,你会真的懂的啦!

2. 引用变量赋值编程题答疑.png

我们来收下尾,公布下文章的三道面试题。

面试官:var a = xxx, a内存中到底保存的是什么?

  • xxx,若是基本数据, 保存的就是这个数据

  • xxx,若是对象, 保存的是对象的地址值

  • xxx,若是一个变量, 保存的xxx的内存内容(可能是基本数据, 也可能是地址值)

面试官:在JS调用函数时传递变量参数时, 是值传递还是引用传递?

一上来跟面试官说:有可能是值传递,也有可能是引用传递。

面试官默默看了手中的答案,这小伙子真™可爱,出现了答案中没有的选项。

面试官刚想喷你的时候,你缓缓说道:

  • 理解1: 都是值(基本/地址值)传递

  • 理解2: 可能是值传递, 也可能是引用传递(地址值)

面试官:此话怎讲?

从胸前拿出一支随身笔,写了答案的缘由

var a = 3
function fn(a){
    a = a + 1
}

fn(a)
console.log(a) // 3

// 以上是值传递


function fn2(obj){
    console.log(obj.name)  // '阿泽' 
}

var obj = { name: '阿泽' }
fn2(obj)  // 传的是内容,恰巧的这个内容刚好是地址值

// 以上是引用传递

复制代码

所以,其实两种答案都是对的,看我们怎么去理解引用传递,可以说是地址值。

地址值也是值传递的一种。

面试官:JS引擎如何管理内存?

  • 内存生命周期
    • 分配小内存空间, 得到它的使用权
    • 存储数据, 可以反复进行操作
    • 释放小内存空间
  • 释放内存
    • 局部变量: 函数执行完自动释放

    • 对象: 成为垃圾对象==>垃圾回收器回收

var a = 3
var obj = {}
obj = undefined  
// 把值设为undefined,并不会释放内存哦,obj还是有值,只不过是undefined而已。

function fn () {
   var b = {}
}

fn() // b是自动释放, b所指向的对象是在后面的某个时刻由垃圾回收器回收
复制代码

最后

终于打完两针疫苗了,
心中的石头如愿落下了,
今年似乎完成一件大事情!
复制代码

以往推荐

Vue-Cli3搭建组件库

Vue实现动态路由(和面试官吹项目亮点)

项目中你不知道的Axios骚操作(手写核心原理、兼容性)

VuePress搭建项目组件文档

koa2+vue+nginx部署

vue-typescript-admin-template后台管理系统

原文链接

juejin.cn/post/699945…

文章分类
前端
文章标签