JS 原型+原型链+继承

JS原型

1.什么是函数对象?

function F1(){};
var F2 = function(){};
var F3 = new function (){};
//F1,F2,F3均为函数对象,实质都是通过new function()创建而来;

2.构造函数

function Person(name,age){
   this.name = name;
   this.age = age;
   this,SayName = function(){
   alert(this.name);
   }
   }
   var person1 = new Person();
   var person2 = new Person();

上述例子中,Person为构造函数,而person1和person2为构造函数的两个实例,而实例会自身带有constructor(构造函数)属性,该属性是一个指针,指向构造函数Person.

person.constructor == Person //true

3.原型对象
每个函数对象对会有一个prototype属性(普通对象没有这个属性),这个属性指向函数的原型对象。

function Person(name,age){
   this.name = name;
   this.age = age;
   this,SayName = function(){
   alert(this.name);
   }
   }
   var person1 = new Person();
   var person2 = new Person();

实际上换一种写法更加清楚:

Person.prototype = {
    name:"wang";
    age:28;
    SayName:function(){};
    }

原型对象就是Person.prototype.
而原型对象会有一个construtor属性,该属性指向构造函数。

Person.prototype.construtor == Person   //  true

3.__proto__属性
JS在创建对象是对会有一个叫做__proto__的内置属性,用于指向创建他的构造函数的原型对象。
例如上述例子中,实例proson1有__proto__属性,而创建它的构造函数为Person,Person构造函数的原型对象就是Person.prototype.

person1.__proto__ ==  Person.prototype   //true

4.原型链
单理解就是原型组成的链,对象的__proto__它的是原型,而原型也是一个对象,也有__proto__属性,原型的__proto__又是原型的原型,就这样可以一直通过__proto__想上找,这就是原型链,当向上找找到Object的原型的时候,这条原型链就算到头了。

 Grand.prototype.LastName = "JS";
    function Grand (){

    }
    var grand = new Grand();
    Father.prototype = grand;
    function Father(){
        this.name = "CSS";
    }
    var father = new Father;
    Son.prototype = father;
    function Son(){

    }
    var son = new Son();
    console.log(son.LastName);  //"JS"
    console.log(son.name);      //"CSS"

JS继承

1.传统形式 --(原型链)
(缺点:过多继承了没有用的东西)

 Grand.prototype.LastName = "JS";
    function Grand (){

    }
    var grand = new Grand();
    Father.prototype = grand;
    function Father(){
        this.name = "CSS";
    }
    var father = new Father;
    Son.prototype = father;
    function Son(){

    }
    var son = new Son();
    console.log(son.LastName);  //"JS"
    console.log(son.name);      //"CSS"

缺点也就是说当我只想继承grand的LastName属性的时候,也会同时继承father的name属性。
2.借用构造函数
(缺点:不能继承借用构造函数得原型;每次构造函数都要做走一个函数)

 //借用构造函数继承
    function Person (name,age,sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    function Student(name,age,sex,grade){
        Person.call(this,name,age,sex);
        this.grade = grade;
    }
    var student = new Student("xiaowang",28,"male","90");

student不能借用构造函数得原型。并且在调用student函数时,会访问到person函数。
3.共享原型
(缺点;不能随意改动自己的原型)

 //共享原型
    Father.prototype.lastname = "KANG";
    function Father (){

    }
    function Son(){

    }
    Son.prototype = Father.prototype;
    var son = new Son();
    var father = new Father();

    //封装方法
    function inherit(Target,Origin){
        Target.prototype = Origin.prototype;
    }
    //引用:必须在继承之前改动原型:inherit(Son,Father)

缺点就是:共享原型中 Son.prototype 和 Father.prototype 指向是同一个空间,改变Son的一个属性,Father的也会跟着改变。
4.圣杯模式
(比较完美)

//圣杯模式
    function inherit(Target,Origin){
        function F(){};
        F.prototype = Origin.prototype;
        Target.prototype = new F();
        Target.prototype.constuctor = Target;
    }
    Father.prototype.LastName = "Deng";
    function Father(){

    }
    function Son(){

    }
    inherit(Son,Father);
    var son = new Son();
    var father = new Father();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值