构造函数与各种继承方法特点

---使用new运算符调用一个函数时,总是返回一个对象

1、当使用new调用任何函数时,它会发生如下事情:

2、后台自动创建一个“空”对象,通过this引用该对象;var this={};//伪代码

3、可任意给this添加属性

4、在函数的末尾隐式返回this

 

但也可以通过下面的步骤返回不同的不同对象:

function Dog(){                      var oDog=new Dog();

    var noThis={noname:"Any"};       oDog.name; //undefined

    this.name="Fod";                 oDog.noname.name;//Any  返回定制的对象(不是this)

    return noThis;//覆盖了

}

当使用new的时候,可以返回一个定制的对象(不是this),如果返回一个非对象(标量值),将会导致返回值被忽略,最终仍会得到this。例如:

 function Dog(){                      var oDog=new Dog();

    this.name="Fod";                  oDog.name; //Fod

    return 1;

}    

当引用一个构造函数的时候,可能会忘记加上new  我们可以通过这个函数以构造函数的方式返回

function Dog(){

    if(!(this instance Dog)){

        return new  Dog(); 

    }

}

 

----//直接字面量继承另外一个直接字面量的属性

function extend(parent){

    var child={};

    for(var name in paret){

        if(parent.hasOwnProperty(naem)){

           child[name]=parent[name]; 

        }

    }

    return child;

}

 

//临时构造函数

function extend(obj){

    var F=function(){};

    F.prototype=o;

    return new F();

}

 

 

function extend(parents,child){

    var F=function(){};

    F.prototype=parent.prototype;

    child.prototype=new F();

    child.prototype.constructor=child;

 

 

 

 

每个对象都连接到一个原型对象,并且可以从中继承属性,所以通过对象字面量创建的对象都连接到Object.prototype----JS标配对象

 

 

----借用构造函数的时候,新对象会得到父对象中的tags成员:

 

    function Parent(){

        this.name=["CSS","JS"];

    }

    Parent.prototype.sayName=function(){console.log(this.name)};

    var oParent=new Parent();

 

    function Child1(){};

    child.prototype=oParent;

    var oChild1=new Child1();

    oChild1.sayName();

 

    function Child2(){       //不能继承原型上的属性或方法

      Parent.call(this);

    }

    var oChild2=new Child2();

    oChild2.sayName();      //Uncaught TypeError: oChild2.sayName is not a function(…)

    console.log(oChild1.hasOwnProperty("name"));  //false 

    console.log(oChild2.hasOwnProperty("name"));  //true

    oChild1.name.push("php"); 

    oChild2.name.push("Java");  //只是一个副本,不能往上级的属性中添加值

    console.log(oParent.name);  //["CSS","JS","php"]

 

------借用和设置原型,父对象的本身属性和原型属性都能得到

    function Child(){

        Parent.apply(this,arguments);

    }

    Child.prototype=new Parent();

    var oChild=new Child();

    oChild.sayName();

 

面向对象:
var obj={};
 Object.defineProperty(obj,"name",{
     writable:false|true,//是否可更改
     ennumerable:false|true,//是否可枚举
     configurable:false|true,//是否可删除
     value:"" //设置值
 });
 
 定义多个属性:
 Object.defineProperties();
 
Object.create();//传入的第一个参数为创建的对象的原型对象
isPrototypeOf();Person.isPrototypeOf(person1);//true|false
Object.getPrototypeOf()获取某实例的原型 //Object.getPrototypeOf(person1);Person.prototype
hasOwnPrototype()//检测一个属性是否存在于实例,该方法是从Object继承而来的
in 操作符
 Object.keys()接受一个对象为参数,返回一个字符串数组——包含了所有的可枚举的属性、
 Object.getOwnPropertyNames()//可枚举或不可的都被返回
 
 prototype的重写以及解决方法
 
 
继承:
实现继承主要是依靠原型链,实现本质就是重写属性原型。
 
存在于被继承的对象实例中所有属性方法,也存在与主动继承的原型中,因为主动继承对象的原型为被继承对象的实例
 
Sub的实例constructor属性指向Sup对象,这是因为主动继承对象原型被重写的缘故——>Sub的原型指向Sup的原型,而Sub的原型的constructor属性指向的是Sup。
 
借用构造函数://只能继承实例中的属性和方法
function Child(name){
    Parent.call(this,name);
}

 

组合继承://会将超类的实例属性继承两次,第一次集成到实例中,第二次继承到原型中,原型中的被覆盖,因此有了后面的组合寄生式继承
function Child(name){    
    Parent.call(this,name);
}
Child.prototype=new Parent();

 

 
原型式继承:
function object(o){
    var F=function(){};
    F.prototype=o;
    return new F();
}
 

 

寄生式继承:
function createAnother(origin){
    var F=function(){};
    F.prototype=o;
    var clone=new F();
    clone.addfn=function(){};//被添加的函数不能复用,效率较低。
}
 

 

 
寄生式组合继承:
var Sub=function(){
    Sup.call(this);
}
function extend(Child,parent){
    var F=function(){};
    F.prototype=Parent.prototype;
    Child.prototype=new F();
}

 

 
posted @ 2016-06-18 16:29  秋虹连宇  阅读(300)  评论(0编辑  收藏  举报