前端—JavaScript基础3
普通对象与函数对象
原型及属性判断
构造函数继承
原型继承
组合继承
寄生组合式继承
//原型是一个对象,其他对象可以通过它实现属性继承
//prototype是函数对象才有的属性
//什么是普通对象? 函数对象?
//函数
function f() {}
console.log(typeof f,f.prototype)
var ff = new f()
console.log(typeof ff,ff.prototype)
//普通对象
var o = {}
console.log(typeof o,o.prototype)
//什么是原型? prototype
//具体原型写法
function Person(){}; //定义一个函数对象
Person.prototype.name = "jack"; //原型中添加属性
Person.prototype.age= 22;
var p1 = new Person(); //实例化
var p2 = new Person();
console.log(p1.name)
//总结:
//1.每一个函数对象都有一个prototype属性,但是普通对象没有;prototype下面又有constructor,指向这个函数;
//2.每一个对象都有一个_proto_内部属性,指向它所对应的构造函数的原型对象;
老家比喻原型:(如下图)
//原型有什么用? 可以实现特性:继承
//生成多个实例 缺点:代码量大,不好组织
var cat1 = {}
cat1.name = "大白"
var cat2 = {}
cat2.name = "小白"
//工厂创建多个对象 缺点:不能够确定类型
function cat(name){
return {
name:name
}
}
var cat1 = cat("大白")
var cat2 = cat("小白")
console.log(cat1 instanceof cat) //false
//构造函数 缺点:存在方法的重复 代码冗余
function Cat(name){
this.name = name;
this.say(){
console.log(this.name)
}
}
var cat1 =new Cat("大白")
var cat2 =new Cat("小白")
console.log(cat1 instanceof Cat) //true
//原型优化 把方法移入到原型中,减少实例的代码
function Cat(name){
this.name = name;
}
Cat.prototype.say = function(){
console.log(this.name)
}
var cat1 =new Cat("大白")
var cat2 =new Cat("小白")
cat1.say()
console.log(cat1 instanceof Cat) //true
//属性检测 是在对象实例中,还是在原型中
console.log('name' in cat1) //会在原型和实例中找
console.log(cat1.hasOwnProperty('name')) //只会在实例中找
//原型应用 继承
function Animal(){
this.type = '动物';
}
function Cat(name){
this.name= name;
}
Cat.prototype = new Animal();
var cat1 = new Cat("小绿");
console.log(cat1.name,cat1.type)
//构造器 继承
function Animal(){
this.type = '动物';
}
function Cat(name){
//Animal.apply(this); //调用Animal构造器 this==Cat
Animal.call(this); //区别(传递参数):Animal.call(this,xx,yy); Animal.apply(this,[xx,yy]);
this.name= name;
}
var cat1 = new Cat("大绿");
console.log(cat1.type)
//组合继承(原型+构造器) 缺点:调用两次父类构造器
function Person(name){
thos.proLans = ["php","java"];
this,name = name;
}
Person.prototype.showName = function(){
console.log(this.name)
}
function Teacher(name,course){
Person.call(this,name);
this.course = course;
}
Teacher.prototype = new Person();
var t1 = new Teacher("aaa","语文");
console.log(t1.course,t1.name,t1.proLans)
t1.showName();
//原型+构造+寄生
function Person(name){
thos.proLans = ["php","java"];
this,name = name;
}
Person.prototype.showName = function(){
console.log(this.name)
}
function Teacher(name,course){
Person.call(this,name);
this.course = course;
}
function extends(subObj,superObj){
//创建一个空对象,将空对象的原型指向superObj的原型
var proObj = Object.create(superObj.prototype); //proObj == 空对象
//proObj.constructor = subObj; //手动将constructor指向构造器
subObj.prototype = proObj; // subObj == Teacher
}
extends(Teacher,Person);
var t1 = new Teacher("小侯","数学");
console.log(t1.course,t1.name,t1.proLans)
t1.showName();
create函数:
function create(o){
var f = function(){};
f.prototype = o;
return new f();
}