<script>
//构造函数--
function Person(name,age){
this.name = name || "TT",
this.age = age || 18;
};
console.dir(Person);
var per = new Person("cc",15);
console.dir(per);
</script>
image.png
image.png创建的构造函数 系统默认有一个
prototype
原型属性,指向原型对象
, 而原型对象有一个constructor
属性 构造器 执行构造函数
, 我们通过 构造函数创建的实例对象
有一个__proto__
属性 指向构造函数的原型的原型对象
-
原型链
:是实例对象和原型对象之间的关系,这个关系是通过实例对象的原型(__proto__
)来联系的,__proto__
指向 构造函数的原型对象
1. 原型的指向是可以发生改变的
//构造函数--
function Person(name,age){
this.name = name || "TT",
this.age = age || 18;
};
console.dir(Person);
var per = new Person("cc",15);
console.dir(per);
function Student(){
};
//原型对象的指向 发生变化
Student.prototype = new Person();
var stu = new Student();
console.log(stu.name);
2.继承
上面我们知道,原型的指向是可以更改的,那么继承是说什么? 继承就是把共有的属性和方法,传递给其子类或者子构造函数
2.1 原型继承
<script>
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
console.log("您好");
};
//构造函数
function Student(){
}
//更改原型指向, 继承person的属性和方法
//注意:Student的原型对象的constructor属性指向的也是 Person 需要更正
Student.prototype = new Person("cc","15")
var stu = new Student();
stu.sayHi();
console.log(stu.name,stu.age);
</script>
- 缺点:stu不能传值给父构造函数,属性值重复
2.2 借用构造函数 ---解决上面的问题
2.2.1 借用方法call
,apply
借用其他对象的属性或者方法,ES给我们提供了有2个这样的属性方法
call
,apply
// call 和 apply 方法
//借用其他对象的方法
var obj = {
name:"cc",
show:function(name ){
console.log("展示自己的方法" + name);
}
};
var obj1 = {
name:"tt",
age:18
};
obj.show();
// obj1借用obj的方法
//call借用其他对象的方法
//参数一:要那个对象借用
//参数二:借用对象方法的参数聊表
obj.show.call(obj1,obj1.name);
//apply方法借用
//参数一:要那个对象借用
//参数二:借用对象方法的参数数组成员,有几个参数,给这个数组传递几个变量
obj.show.apply(obj1,[obj1.name]);
2.2.2 借用构造函数
<script>
function Person(name,age){
this.name = name;
this.age = age;
}
//借用构造函数:构造函数名字.call(当前对象,属性,属性,属性....);
//解决了属性继承,并且值不重复的问题
//缺陷:父级类别中的方法不能继承
function Student(name,age,score){
Person.call(this,name,age);
this.score = score;
}
var stu = new Student("cc",15,90);
console.log(stu.name,stu.age,stu.score);
</script>
缺陷:父级类别中的方法不能继承
2.3组合继承 = 原型 + 借用构造函数
<script>
//组合继承 = 原型继承 + 借用构造函数继承
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
};
Person.prototype.sayHi = function(){
console.log("hello,您好");
};
function Student (name,age,sex,score){
//借用构造函数
Person.call(this,name,age,sex);
this.score = score;
};
//通过原型继承 访问方法
Student.prototype = new Person();
var stu = new Student("cc",15,"男",90);
stu.sayHi();
console.log(stu.name,stu.age,stu.sex,stu.score);
</script>
3.对象的小补充
我们知道对象是一个 key-value的键值组合,在JS中key是一个字符串,如果key对应的是其他的对象的话,那么这个对象的内部就会调用
toString()
方法,转化为字符串
<script>
var a = {name:"cc"};
console.log(a.toString()); // 转为字符串"[object object]";
var c = {};
c[a] = "test1"; // c[[object object]] = "test1";
console.log(c);
// 打印结果:{[object Object]: "test1"}
</script>
打印结果.png
<script>
var a = {name:"cc"};
var c = {};
var b = {};
c[a] = "test1";
c[b] = "test2";
console.log(c[a]);
打印结果是: test2
原因是: key的值相同,覆盖掉了原本的
</script>
4.拷贝
4.1浅拷贝 :拷贝的是 地址,
var obj = {name:"cc",age:"18",car:{
type:"大众"
}};
var obj2 = {};
for(var key in obj){
obj2[key] = obj[key];
}
console.log(obj2);
obj2.car.type = "TT";
console.log(obj);
image.png
4.2深拷贝:拷贝的数据内容
- 先提供一个函数,这个函数有2个参数,一个是目标对象,一个要拷贝属性的对象
- 需要判断第一参数是否有值,如果没有,赋值为空对象
- for..in遍历第2参数, 判断属性值的类型
1.如果是值类型(函数),直接赋值
2.如果是引用类型,再调用一次这个方法,拷贝这个属性存储的内容
<script>
/*
原理:
*/
function deepCopy(targetObj,copyObj){
targetObj = targetObj || {};
for(var key in copyObj){
//判断是不是实例属性
if(copyObj.hasOwnProperty(key)){
//判断 对应的key的value是不是对象
if(typeof copyObj[key] == "object"){
//处理动态的添加属性
targetObj[key] = Array.isArray(copyObj[key]) ? [] :{};
deepCopy(targetObj[key],copyObj[key]);
}else{
targetObj[key] = copyObj[key];
}
}
}
}
var obj = {name:"cc",age:"18",car:{
type:"大众"
}};
var obj2 = {};
deepCopy(obj2,obj);
obj2.car.type = "上海荣威";
console.log(obj2);
console.log(obj);
</script>
image.png
网友评论