js中 构造函数,原型,和实例化对象

1,构造函数创建对象造成的内存浪费,和原型的引入

 function Person(name,age){
        this.name = name;
        this.age = age;
        this.introduce = function(){
            alert('我是'+this.name)
        };
    }



    var  p1 = new Person('小敏',12);

    var  p2 = new Person('小敏',12);
    var  p3 = new Person('小敏',12);
//.....................

如上不断地实例化Person对象,每次实例化都要为intrduce方法开辟新的内存空间,这样做浪费了内存空间

下面想了一个办法,在外部为方法写一个函数,让对象中的方法指向这个函数,当对象调用方法时,通过属性指向方法函数所在的地址,

那么就可以实现多个对象公用一个方法函数

 function introduce(){
        alert('我是'+this.name);
    }
    // var introduce = '你好';  //缺点当其他人定义变量与函数名相同时,会报错
    function Person(name,age){
        this.name = name;
        this.age = age;
        this.introduce = introduce;
    }
    //实例化对象
    var  p1 = new Person('小敏',12);
    var  p2 = new Person('小明',12);
    p1.introduce(); //第5行有效 则 这里会报错

    // console.log(p1.introduce == p2.introduce); //true

上面的代码依然存在缺陷,封装对象后,假如其他人看不到源码的情况下,且定义了一个与方法函数名相同的变量,那么这个程序将会报错,程序不能正常运行.

下面我们引入原型,prototype

原型存在于每个函数对象中,是函数对象的属性    函数名.prototype.方法名 = function(){函数体}    (当然我们也可以通过这种方式为构造函数添加属性)

 function Person(name,age){
        this.name = name;
        this.age = age;
    }
    Person.prototype.introduce = function(){//prototype  原型,模式
        alert('我是'+this.name);
    };

    //实例化对象
    var  p1 = new Person('小敏',12);
    var  p2 = new Person('小明',12);
    p1.introduce();

    console.log(p1.introduce == p2.introduce); //true

3,构造函数  原型  实例化对象   之间的关系

构造函数中存在一个属性叫  prototype  也就是原型,原型本身又是一个对象,它内部存储着  constructor 构造器,还用用户定义的需要共享的属性以及方法

prototype 原型对象中的constructor属性 指向的是prototype自己所在的构造函数

在实例化对象中存在着一个叫 __proto__的属性,同时它本身是一个对象,确切地说  它指向构造函数中的 prototype对象所在的内存空间,所以  __proto__ ==Prototype ,

但是__proto__是一个非标准化的对象,  它内部的方法 可以直接 被它的父级对象直接调用,  如上段代码中  introduce方法在 __proto__对象中, __proto__是p1的属性, 正常调用方式是  p1.__proto__.introduce(),   由于__proto__的非标准化, p1.introduce()  调用方法也是行得通的.

猜你喜欢

转载自blog.csdn.net/qq_42039281/article/details/82763763
今日推荐