js中的数据按照存储的内容不同进行划分可以分为值类型和引用类型
变量 = 内容
值类型:
保存的是值(具体的数据)。
基本数据类型都是值类型的:string | number | boolean | null | undefined
引用类型:
保存的是引用(reference - 地址),这个引用指向内存中的一块具体数据。
所有的对象类型Object类型都是引用类型
复合数据类型本质上都是Object类型的。
值类型的赋值操作
把等号右边变量的内容(具体的数据)复制一份给左边的变量
特点:修改了其中一个值,对另外一个值没有影响,他们是相互独立的
引用类型的赋值操作
把等号右边变量的内容(地址)复制一份给左边的变量
特点:修改了其中一个值,对另外一个值有影响,他们共享内存中的同一块数据
属性拷贝实现继承:
-
如果属性是引用类型的那么有共享的问题
- 属性拷贝和直接赋值的区别:
直接赋值:所有的数据都是共享的
属性拷贝:仅仅引用类型是共享的 - 重新设置引用类型的值:
直接赋值:重新设置某个对象的引用类型值,那么另外一个对象会受到影响
属性拷贝:重新设置某个对象的引用类型值,那么另外一个对象不会受到影响会切断他们之间的关系
- 属性拷贝和直接赋值的区别:
对象的动态特性:
对象创建之后还可以动态的修改:
增加|修改|删除 (属性+方法) = 成员-
动态特性
- 增加:在赋值的时候会先在对象上面搜索属性,如果该属性不存在那么就新增一个属性
- 修改:在赋值的时候会先在对象上面搜索属性,如果该属性存在那么就修改这个属性的值
- 删除:delete关键字
原型式继承
1.利用动态特性
2.直接替换原型对象
3.设置子构造函数的原型对象 = 父构造函数的原型对象
原型链继承
子构造函数.prototype = new 父构造函数()
属性拷贝
浅拷贝:for..in循环直接拷贝(引用类型的属性共享)
深拷贝:
使用for..in来遍历
如果是值类型,直接赋值
如果是引用类型,新创建一个对象,再次遍历..持续这个过程Array.isArray()
作用:判断某个对象是否是数组
使用方法:Array.isArray(对象)
返回值:布尔类型的值(true|false)
注意点:兼容性问题(ES5)优质继承写法事例
function deepCopy(obj1,obj2) {
obj1 = obj1 || {}; //容错性处理
for(var i in obj2)
{
//只拷贝实例属性
if (obj2.hasOwnProperty(i))
{
if (typeof obj2[i] == "object")
{
//引用类型,新创建对象,再次遍历
//需要判断是数组还是对象
obj1[i] = Array.isArray(obj2[i])?[]:{};
deepCopy(obj1[i],obj2[i]);
}else
{
obj1[i] = obj2[i];
}
}
}
}
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.showName = function () {
console.log(this.name);
}
Person.prototype.hi = "hi";
function Boy(name,age) {
//构造函数内部会默认创建空对象并赋值给this
Person.call(this,name,age); //this.name = name; 借用构造函数
}
deepCopy(Boy.prototype,Person.prototype);
var boy1 = new Boy("张三",20);
var boy2 = new Boy("李四",30);
console.log(boy1);
console.log(boy2);
boy1.showName();
console.log(boy1.hi);
Boy.prototype.hi = "hahahahah";
console.log(boy1.hi);
var p1 = new Person();
console.log(p1.hi);