继承
需要在某一个对象或者类的基础上,保留原有内容的同时,扩展出一些新东西
一、对象的继承
1、一个JSON对象,属性值只有JSON、数组、数字、字符串,没有函数。可以使用JSON.parse 和 JSON.stringify搭配实现对象的继承。
var zhangsan={
x:10,
y:20,
z:30
}
var lisi=JSON.parse(JSON.stringify(zhangsan));
2、深拷贝
使用forIn循环+递归,将原对象的值依次赋予新对象
//适应范围:不支持JSON.parse()和JSON.stringify()的浏览器;
对象为数组
function Clone(obj){
var o=Array.isArray(obj)?[]:{};
for(var key in obj){
if(/object/i.test(typeof obj[key])){
o[key]=Clone(obj[key]);
}else{
o[key]=obj[key];
}
}
return o;
}
备注:判断对象是不是数组 Array.isArray(obj);
或者Object.prototype.toString.call(obj);
二、函数的继承(原型链实现)
原型链共有三种书写方式,第三种不兼容IE6 7 8,因为IE6 7 8不支持Object方法的使用
1、类的继承
function Person(name,address){
this.name=name;
this.address=address;
}
Person.prototype.show=function(){
console.log("名字是:"+this.name+"\n地址是:"+this.address);
}
function Student(){
Person.apply(this,arguments); //继承Person的方法
}
Student.prototype=new Person(); //此步继承Person的原型方法和变量
//1、继承Person的原型,不可以使用new Person(name,address);因为此时的参数是全局变量
//2、但是,这里会无端的调用了一次Person(),如果Person类的内容很多的话,非常影响JS性能,以下两项的作用都是优化此处。
//Student.prototype=Person.prototype;
//不行,这是引用,Student原型的改变会引起Person原型的改变
var xyong=new Student("xyong","青岛");
//和第45行的代码一起完成对Person方法的继承
xyong.show();
2、原型继承(优化)
function Person(name,address){
this.name=name;
this.address=address;
}
Person.prototype.show=function(){
console.log("名字是:"+this.name+"\n地址是:"+this.address);
}
function Student(){
Person.apply(this,arguments);
}
function Fn(){}
Fn.prototype = Person.prototype;
Student.prototype = new Fn(); //Student.prototype的改变相当于影响了Fn实例对象私有属性的改变,Fn实例私有属性的改变不会影响Fn.prototype的改变,即也不会影响Person.prototype的改变
Student.prototype.tel = 110;
//上面的操作会使Student.prototype的constructor指向Fn,因此需要改变constructor的指向
Object.defineProperty(Student.prototype,"constructor",{
value:Student
});
var xyong=new Student("xyong","青岛");
xyong.show();
3、Object.create()的使用
function Person(name,address){
this.name=name;
this.address=address;
}
Person.prototype.show=function(){
console.log("名字是:"+this.name+"\n地址是:"+this.address);
}
function Student(){
Person.apply(this,arguments);
}
//直接使用Object.create();作用和第二项的相同,
//Student.prototype = Object.create(Person.prototype);
//Object.create()中还可以传递参数,因此我们可以顺便将Student.prototype的constructor指向修改一下
Student.prototype = Object.create(Person.prototype,{
tel:{
configurable:true,
writable:true,
enumerable:true,
value:110
},
constructor:{
configurable:false,
writable:false,
enumerable:false,
value:Student
}
});
console.log(Student.prototype);
console.log(Person.prototype);