<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
/*
对象创建:我认为只用3种即可!
*/
/*
第一种
*/
function Obj1(name,age){
this.name=name;
this.age=age;
}
Obj1.prototype.showMessage=function(){
console.log("Obj1的属性:名字:"+this.name+",年龄:"+this.age);
}
var obj1=new Obj1("万恶的小明",18);
obj1.showMessage();
/*构造函数式创建,这种方式实例化的对象都是通过原型模板来创建的基本创建语句只用写一次*/
obj1.getContent=function(){
console.log("这是Obj1模板构建出来的对象之一");
}
/**
* 所有对象通用一个原型模板后期可以给想要添加方法或属性的实例化对象添加 不会影响其他对象且不用重复去写创建类模板的语句
* 这是用java的人最熟悉只有小改动
* 他的优势应该在于方便去创建不确定的属性,
*/
/*第二种是直接创建对象,他适合用于使用一次就丢,且属性确定的对象*/
var obj2={
name:'obj2',
age:15,
howMessage:function(){
console.log("Obj1的属性:名字:"+this.name+",年龄:"+this.age);
}
}
/*三就是工厂模式
* 可以用来快速创建对象*/
function Person(name,age){
var obj={
name:name,
age:age,
howMessage:function(){
console.log("Obj1的属性:名字:"+this.name+",年龄:"+this.age);
}
}
return obj;
}
console.log('-------------------------------------')
/************************************************js中的继承**********************************************/
function SuperFather()
{
console.log("父类构造")
}
SuperFather.prototype.superShow=function(){
console.log("父类show方法")
}
function SubSon(){
console.log("子类构造")
}
SubSon.prototype.subShow=function(){
console.log("子类show方法")
}
//SubSon.prototype=SuperFather.prototype;//
//这两种方法只是让子类中所有原型属性变成父类的原型属性,但构造不变,子类原型中的属性全部被替换
//var h1=new SubSon();
console.log('-------------------------------------')
SubSon.prototype=new SuperFather();
h1=new SubSon();
SubSon.constructor();
SubSon.prototype.constructor();
console.log('摊牌---------------');
/*
算了直接摊牌吧
这应该是原型的继承
*/
//1.SubSon.prototype=SuperFather.prototype;
// 2.SubSon.prototype=new SuperFather();
/*
他是这样的1.类型的继承他是子原型只继承(实质是替换和增添)父原型的原型属性 无法调用父类的构造
2.他是将整个实例(实例就是构造函数+原型(模板的)属性全部给塞到子原型的原型属性中,子的原型属性就是实例对象,可以调用父类的所有原型属性与构造函数,)
优点是:父类的一切都可被子类继承使用,子类还可在原型中继续添加新的属性增强
缺点中:1.继承单一 X: 我不认为他继承单一给子类原型中添加任意属性 ,属性赋值父类的实例得到父类的一切 可多个 //但是这里我有自己的见解 反正不急
2:所有新实例都会共享父类原型的属性 父类原型的改变会改变各个子类 比如添加或删除原型中的属性
3. 新实例无法向父类构造函数传参
//我的js高级其实已经全部看完了,现在就是清算
//因为看完啦之后要比对一下 自我认知
//我在看别人的博客来理解
//我觉得比较好的博客:https://www.cnblogs.com/ranyonsue/p/11201730.html
*/
/*构造函数的继承*/
console.log('-------------------------------------')
function FunExtend(){
SuperFather.call(this);
}
var fun1=new FunExtend();
fun1.superShow;//为什么可以运行呢?
/*先不管他,先看下借用构造函数继承会初始化原型的属性么*/
function OtherSuper(name){
this.name="原型中的"+name;
}
OtherSuper.prototype.showName=function(){
console.log("名字是:"+this.name);
}
var Os1=new OtherSuper();
Os1.showName();
console.log("原型中的name:"+Os1.name);//测试他是否在原型中
function FunExtend2(){
OtherSuper.call(this,"牛马");
}
FunExtend2();
console.log(OtherSuper.prototype.name);
var oss= new FunExtend2();
console.log(oss.name);
console.log(oss.__proto__.name);
/*上面不用看了*/
/*
借用构造函数继承确实是:
只会继承父构造函数中使用的原型属性其他原型属性都不会继承
他可以继承多个构造函数的使用原型属性
*/
/*
如果是借用构造函数来继承直接调用子类构造函数父类原型中的一切不会被改变 他可能是因为模板只能是一开始构建好后期的未实例化赋值不会改变原型中的值
函数执行后立即释放了相当于穿的值只在调用子类构造函数时有用出来后没了
只有是实例化对象后借用函数构造继承的值会被保留在对象中
*/
console.log('-------------------------------------')
/*
下面是借用构造函数与原型继承的组合使用 ;目的是为了让他即可以先继承父类的所有原型方法与构造函数 然后再通过实例化来将父构造函数中使用的对象属性初始化
*/
function MyFather(name){
this.name=name;
}
MyFather.prototype.e=function(){
console.log(this.name+"身体异常,饥饿迅速");
}
function SonMy(){
MyFather.call(this,"父亲");
}
SonMy.prototype=new MyFather();//不能把他放在构造函数中,构造函数也是隐式的初始化他的原型,
var zx=new SonMy();//我是懒得再填写参数
zx.e();
/*不仅继承了父类的所有还初始化了原型属性,但是他们都有一个缺点那就是无法防止父类原型的后期修改导致的变化*/
MyFather.prototype.cc=function(){
console.log('多出来的方法')
}
zx.cc();
console.log('-------------------------------------')
/*
重点!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
function content(obj){
function F(){
}
F.prototype=obj; //我发现这原型实例的继承会使构造器也变成父类的,所以不要去用实例去构建原型 用他的原型去构建传递给中间人的原型
return new F();
}//单看这个是没有什么意思 类似于一个工厂 ,但是其实我们忽略了一点他是一个闭包 初级的闭包只认为是嵌套函数内函数引用外函数的变量
//他其实是内函数导致外函数的变量没有被释放,内存地址一直被指向
//那他这也是他为了不让父类原型的改变导致后面其他对象的改变所以
//让父原型中的所有给到另一个函数原型中,这个函数原型无法被外部访问是私有的
//返回的只是一个实例化对象!
//这就避免了这个中间函数原型的释放以及对父原型的修改导致子对象的变化
console.log('-------------------------------------')
//他现在就是已经得到了私有原型的对象了但是他如果父原型的某些方法要使用某些需要需要初始化的属性值 我们需要对他的值进行 改动 要么是调用构造
///要么就是将需要赋值的属性直接赋值
function Son(){
MyFather.call(this,"Father");
}
var ct=content(MyFather.prototype)
console.log(ct.constructor)//敲!原型的继承也会导致构造器的变化
Son.prototype=ct;
Son.prototype.constructor=Son;
var sonC=new Son();
console.log(sonC.constructor);
sonC.e();
MyFather.prototype.ll="d";
console.log(sonC.ll);
console.log(sonC.__proto__);
/*焯,我不明白为什么还能受变化,算了就这样干,没人问啊草,算了还是快点把前搞完,继承有些方面竟然不能*/
/*
敲,这个继承我知道怎么做不知道,为什么没有办法我已经是闭包的原型了为什么父类的改动还是会体现在子类上,这就是自学的坏处,没有人可以问,
没办法理解到哪里就是哪里,我还是有点失败
*/
</script>
</body>
</html>
|