美文网首页
变量提升的坑以及对象键值拷贝方式?

变量提升的坑以及对象键值拷贝方式?

作者: BIGHAI | 来源:发表于2017-06-01 18:46 被阅读0次

遇到一个不明白的问题:

var obj_out = {"a": 1, "obj_in": obj}
var obj = {"a": 2, "fun": function(){console.log(this.a)}}
try{
  obj_out.obj_in.fun()
}catch(err){
  console.error(err)//TypeError
}
console.log(typeof obj_out.obj_in)//undefined

?????????????????????????????????????????????????
感觉这是变量提升的锅,进行验证

var obj = {"a": 1, "fun": function(){console.log(this.a)}}
var obj_out = {"a": 6, "obj_in": obj}
obj_out.obj_in.fun()//1

分析:我们通过前面的学习知道,在JavaScript中,他的代码在开始运行之前会首先进行词法分析,接着语法分析,然后才是开始运行。更加挑明了说的话,在代码运行前,编译器会首先找到所有的声明然后将他们放到相应的位置。具体细节可以看看前面的提升一文,而这种现象被称作变量提升现象。对应到这里的例子就是:在运行之前,obj和obj_out会被提升为undefined,但是对于a,fun,obj_in这些就不会被提升了。接着就开始运行,运行第一行代码的时候,引擎对作用域发起一个LHS查询obj,由于提升的原因,很显然能够将其找到,于是对其进行赋值,属性a的值为1,属性obj_in的值为obj,此时引擎会发起一个RHS查询obj,由于能够在当前作用域找到,所以此时利用找到的值——经过变量提升后为undefined的obj,注意这里的RHS查询只是将值拷贝给obj_in属性,而不是obj_in指向obj,如果是指向的话,那么经过后续的操作之后就不会是undefined了。那么如何证明这里是深拷贝,而非浅拷贝呢?

下面就证明对于利用字面量构建对象时,以及给对象动态添加属性时,如果对象的一个属性指向的值时引用类型的对象的话,那么此时将引用类型对象这个值赋值给某个属性的时候,利用的将是深拷贝。

var fun = function(){console.log("jiajishuiji")}
var obj = {"a": 1, "fun": fun}
fun = function(){console.log("jiagoushuigou")}
obj.fun()//"jiajishuiji"
var fun2 = function(){console.log("before")}
var obj2 = {}
obj2.fun = fun2
fun2 = function(){console.log("after")}
obj2.fun()//"before"

通过上面的例子我们可以知道,如果对象的属性的值是一个引用类型的值的话,那么此时将对象的key和value关联起来的时候利用的是深拷贝。

其实,仔细想一想这里根本就不涉及深浅拷贝的问题,因为"obj_in"的值是undefined,而它是非引用类型的值,对于非引用类型的值来说,其拷贝行为只有一个表现那就是:深拷贝。

举一反三:看看下面这个例子

var obj = {"fun": foo}
function foo(){console.log("hihi")}
obj.fun()

上面的结果是什么?正确答案是"hihi",这里也是变量提升,不过变量被提升为了其本应具有的类型-即函数类型。

END

相关文章

  • 变量提升的坑以及对象键值拷贝方式?

    遇到一个不明白的问题: ?????????????????????????????????????????????...

  • Java对象拷贝

    常用的对象拷贝有2种方式,分别是浅拷贝,深拷贝。 1. 浅拷贝 在浅拷贝中,如果原型对象的成员变量是值类型,将复制...

  • Java-序列化—(三)序列化实现深拷贝

    浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象...

  • Java 对象克隆

    Java的拷贝可以分为浅拷贝和深拷贝。 浅拷贝 原变量和拷贝变量引用同一个对象,改变一个变量锁引用的对象将会对另一...

  • 引用赋值和浅拷贝和深拷贝

    1.对象的引用赋值 2.对象的浅拷贝 浅拷贝:是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象...

  • IOS

    一、IOS基础 1、浅拷贝与深拷贝浅拷贝:拷贝对象的指针成员变量和原对象的指针成员变量指向同一块内存空间。深拷贝:...

  • Python 相关

    Python copy以及其中的deepcopy可以拷贝python类对象,深度复制,对于想快速复制对象中的变量特...

  • 集合深浅拷贝以及经常遇到的坑(面试常问)

    集合深浅拷贝以及经常遇到的坑(面试常问) 集合深浅拷贝以及经常遇到的坑(面试常问)

  • PHP之剑走偏锋的DeepCopy

    php的深拷贝和浅拷贝问题,普通变量对象的赋值 = 是深拷贝,& 是浅拷贝。 输出结果: 类对象的拷贝问题就得看下...

  • 对象拷贝

    浅拷贝 什么是浅拷贝 浅拷贝会将原对象中的基本类型的变量的值和引用类型变量的值复制到新的对象中。浅复制得到的新对象...

网友评论

      本文标题:变量提升的坑以及对象键值拷贝方式?

      本文链接:https://www.haomeiwen.com/subject/gpbefxtx.html