0%

引用对象的复制


之前讲到了javaScript的类型分为基本类型和引用类型,今天分享一下我的学习心得,引用类型应该怎样正确的复制

javaScript 变量类型

之前学习的过程中有提到过javascript的变量类型分为 基本类型和引用类型,这两个具体有什么区别了?

基本类型:存放在栈中,基本类型直接储存的是数值

引用类型:存放在堆中,引用类型储存的是数据的内存地址(我们拿到手的变量其实就是一个指针)

变量复制的问题

只是讲概念性的东西并不能真正的了解到 基本类型 和 引用类型在使用上面的区别,我做一个简单的例子,变量的复制

变量的复制分为两种情况:基本类型的复制 和 引用类型的复制

基本类型的复制:

1
2
3
4
5
var a =10;
var b = a;
b = 20;
console.log(b); // 20
console.log(a); // 10

这里我们会发现,将a的值赋值给b后再修改b的值,并不会影响a的值,一切使用正常.

引用类型的复制:

1
2
3
4
5
6
7
8
9
10

var obj1 = {
name:'张三'
}
var obj2 = obj1;

obj2.name = '李四';

console.log(obj1.name); // 李四
console.log(obj2.name); // 李四

我们会很奇怪的发现,明明修改的是obj2的值,为什么obj1的值也会发生改变,这就是之前所说的,引用类型储存的是数据的内存地址

通过上面的讨论,得到了两个结论 :

  1. 基本类型是直接操作 值
  2. 引用类型直接操作的是 : 内存地址

那要如何解决引用类型复制的问题了??

工厂模式与构造函数

解决引用类型复制的问题可以通过两种方法,工厂模式与构造函数

工厂模式

工厂模式,顾名思义就是类似于工厂的生产模式,分为三大步

  1. 原型 – var obj = new Object();

  2. 加工 – obj.属性或方法

  3. 出厂 – return obj;

1
2
3
4
5
6
7
8
9
10
11
function createObject(name){
var obj = new Object();
obj.name = name;
obj.fun = function(){
console.log(this.name + '你好' )
}
return obj;
}

var obj1 = createObject('对象1');
var obj2 = createObject('对象2');

这时候再去修改 obj2 , obj1就不会发生改变了,有几个地方需要注意的(踩了一个大坑):

我们再创建一个 对象

1
2
3
var dog = {
name:'狗'
}

首先,obj.fun 的这个方法中,不要去使用obj.name,因为在js中,一个对象的方法可以被其他的对象所调用,
可以通过call、apple 就能实现,如果这里写obj.name,那么obj1.fun.call(dog);输出的结果仍然是obj1的信息,
所以应该使用this,这里的this指向调用该方法的本身,谁调用就是谁

call、apple 具体的使用下次再说,这里只是作为了解

构造函数

  1. 默认函数首字母大写

  2. 构造函数并没有显示返回任何东西。new 操作符会自动创建给定的类型并返回他们,当调用构造函数时,new会自动创建this对象,且类型就是构造函数类型。

  3. 也可以在构造函数中显示调用return.如果返回的值是一个对象,它会代替新创建的对象实例返回。如果返回的值是一个原始类型,它会被忽略,新创建的实例会被返回。

1
2
3
4
5
6
7
8
function People(name){
this.name = name;
this.fun = function(){
console.log(this.name + '你好');
}
}

var student = new People('小明');

这样是一个基本的构造函数,一样可以解决引用对象的复制问题,但是像fun这样的函数,相同的属性容易占内存,所以写在公共的区域: 原型(protoType)

1
2
3
People.prototype.fun = function(){
alert(this.name + ': 汪汪汪!');
}

这样数据就存在protoType里,调用是可以直接打点调用, 原型(protoType) 之后再和大家分享

以上就是个人的学习心得,感谢各位大神指出错误和不足

-------------本文结束感谢您的阅读-------------
没办法,总要恰饭的嘛~~