万物皆对象,一切皆可点
一、面向对象(概述)
- 1,通过
new function(){}
函数返回的对象 - 2,通过
new
执行的函数,在最开始的时候创建一个对象,函数this
指向这个对象 - 3,通过执行这个函数最终返回创建的对象
1、对象创建.此处以构造函数为例
function createGF(breast , legs , bf ){
var obj = {}; //新建一个对象
obj.sex = "女";
obj.breast = breast;
obj.legs = legs;
obj.bf = bf;
obj.show = function () {
alert( "我是" + this.bf + "的女朋友!" );
};
obj.showAttr = function () {
alert( "胸"+this.breast+','+"腿"+this.legs );
}; //以上为函数的属性也成为实例
return obj;\\返回开始创建的对象
}
var obj = createGF("normal","normal","dd")//执行返回一个对象obj,obj有上述属性
注:上述方法函数指向返回obj与下面构造函数 new执行返回相同
var obj = new createGF("normal","normal","dd")//this指向obj
function createGF(breast , legs , bf ){
this.sex = "女";
this.breast = breast;
this.legs = legs;
this.bf = bf;
this.show = function () {
alert( "我是" + this.bf + "的女朋友!" );
};
obj.showAttr = function () {
alert( "胸"+this.breast+','+"腿"+this.legs );
}; //以上为函数的属性也成为实例
}
二、构造函数的原型(只有构造函数才有原型)
原型prototype:
- 构造函数才有prototype
- 一般用来存放实例化对象的 公共 属性/方法
- 实例化对象的私有属性,放在构造函数里面
- 实例化对象的公共属性,放在构造函数原型里面
2、以上面构造函数为例
function CreateGF(breast , legs , bf ){
this.breast = breast;
this.legs = legs;
this.bf = bf;
}
//将公共属性放在构造函数原型中
CreateGF.prototype.sex = "女";
CreateGF.prototype.show = function () {
alert( "我是" + this.bf + "的女朋友!" );
};
CreateGF.prototype.showAttr = function () {
alert( "胸"+this.breast+','+"腿"+this.legs );
constructor : CreateGF//修正constructor 指向,指向构造函数本身
};
var ddGF = new CreateGF("big" , "long" , "dd");
//我们查看ddGF的内容
如图:
ddGF 实例化的内容.png注:图中的constructor属性指向构造函数本身,在使用原型的时候需要加上constructor : CreateGF来修正constructor 指向
二、(扩展)对象的原型链
- 原型链:
每个对象,都有一个 proto 属性,指向该对象对应的构造函数原型; - 而构造函数的原型又是一个对象,也有对应的构造函数,它的proto也会指向它构造函数的原型;
- 最终直到 Object.prototype 为止
寻找对象的顺序
- 1、对象在找某个属性的时候,
- 2、会先从私有属性开始找,
- 3、找不到的话,往proto里面去找,
- 4、再找不到依次往上,直到Object.prototype 为止,
- 5、还找不到的话,才会弹出undefined;
- 图例,寻找过程
- 最后形成原型链
三、对象的继承(灵魂)
-
继承:
-
在父类的基础上,变化一些东西
-
儿子继承爸爸
-
儿子拥有爸爸的所有东西
-
儿子可以扩展新东西,且不能影响爸爸
对象继承 1————(类继承)
//父类
function GF(){
this.breast = arguments[0];
this.legs = arguments[1];
this.bf = arguments[2];
}
GF.prototype = {
constructor : GF,
sex : "女",
show : function () {
alert( "我是"+ this.bf +"的女朋友" );
}
};
//子类
function GFchild() {
this.height = arguments[0];
}
GFchild.prototype = new GF("big" , "long" , "dd");
GFchild.prototype.constructor = GFchild;
GFchild.prototype.showH = function () {//子类的原型属性
alert( "我身高"+this.height+"cm" );
};
//子类的实例化
var a = new GFchild("170");//参数只有父类实例化已经写好的
//父类的实例化
var dd = new GF("big" , "long" , "dd");
//我们来查看子类实例
console.log(a)
图例(子类继承之后实例化的对象)
子类继承之后实例化的对象.png类继承的问题
问题:
- 没法传参
- 本应该私有的属性变为了公共属性,如果该属性是引用型,一旦发生改变就会有很大的问题
2————构造函数继承(精髓)
//父类
function GF(){
this.breast = arguments[0];
this.legs = arguments[1];
this.bf = arguments[2];
}
GF.prototype = {
constructor : GF,
sex : "女",
show : function () {
alert( "我是"+ this.bf +"的女朋友" );
}
};
//子类
function GFchild() {
GF.apply(this,[].slice.call(arguments));//此处是精髓
//构造函数在子类函数内执行即可传参
this.height = arguments[3];//子类属性
}
GFchild.prototype = new GF();
GFchild.prototype.constructor = GFchild;
GFchild.prototype.showH = function () {
alert( "我身高"+this.height+"cm" );
};
//子类的实例化
var a = new GFchild("big","long","dd","170");
图例(构造函数继承方式----精髓)
构造函数继承.png此处我们可以看出子类私有属性拥有了父类的私有属性,但是凡事都有但是——————问题!!!
GFchild.prototype = new GF();//此处将出现undefined情况,子类的原型中有父类的私有属性但是并未传值,所以为undefined,解决办法,往下看
3————原型继承
GFchild.prototype = new GF();//此方法继承的运行为undefined
——————解决办法——————引用空函数来继承原型————
//原型的继承
function F() {}
F.prototype = GF.prototype;
GFchild.prototype = new F();//其余部分不变,此处只继承了GF的原型,私有属性在之构造函数已经继承了此时undefined都消失,并且很干净哦
图例
完美继承.png到这里继承已经相当完美了需要注意的
GF.prototype = {
constructor : GF,
sex : "女",
show : function () {
alert( "我是"+ this.bf +"的女朋友" );
}
};
GFchild.prototype.showH = function () {
alert( "我身高"+this.height+"cm" );
};
GFchild.prototype.constructor = GFchild;
- 对比这两个原型写法。 父类原型很多的时候可以写为json并为constructor做修正 ,但是——————子类在写原型的时候需要注以不可以写json形式,只能点操作。(没有记错的话)同样要为constructor做修正 。
网友评论