JS原型和原型链

原型和原型链在JS中是比较复杂的一块,接下里开始我们基础知识的学习

  1.prototype和__proto__的区别:prototype原型对象只有函数才拥有的属性,__proto__是所有对象都拥有的属性。

var a = {};
console.log(a.prototype);  //undefined
console.log(a.__proto__);  //Object {}

var b = function(){}
console.log(b.prototype);  //b {}
console.log(b.__proto__);  //function() {}

  prototype可以实现在一个构造函数中定义的方法和属性达到高度的重用性,科学使用

  当我们在构造函数中这样定义一个变量和方法的时候,我们实例化的对象是不能访问到的,这样的变量和方法我们叫做静态变量和静态函数

function person(){
            person.a=0//实例变量
            person.fun=function(){//实例方法
                
            }
            console.log(person.a);//0
            console.log(person.fun);//function
        }
        var child = new person();
        console.log(child.a);//undefined
        console.log(child.fun);//undefined

  当然我们也希望我们在构造函数中定义的变量和方法在我们的实例化对象中能够访问到

    function person(){
            this.a=[]//实例变量
            this.fun=function(){//实例方法
                
            }
        }
        var child1 = new person();
        var child2 = new person();
        child1.a.push(1);
        console.log(child1.a);//1
        console.log(child2.a)//""

  上面的代码符合了我们的需求,但是我们发现我们实例化的child1和child2,并不会共享我们的变量和函数,说明child1和child2中定义的方法和变量不是同一个引用而是对person的复制,属性并不会有影响但是方法有,如果一个函数对象有上千和实例方法,那么它的每个实例都要保持一份上千个方法的复制,这显然是不科学的,这可肿么办呢,prototype应运而生。

function Person(name){
                this.name=name;
            }

            Person.prototype.share=[];

            Person.prototype.printName=function(){
                console.log(this.name);
            }
            var child1= new Person("123");
            var child2 = new Person("1456");
            child1.share.push(1);
            child2.share.push(2);
            child1.printName();
            child2.printName();
            console.log(child1.share);//1,2

  可以构建一个科学些的、复用率高的对象,如果希望实例对象的属性或函数为同一个引用则定义到prototype中,如果希望每个实例单独拥有的属性或方法则定义到this中,可以通过构造函数传递实例化参数。

  2.constructor:默认情况下,所有的原型对象都会自动获取一个constructor属性,这个属性指向prototype属性所在的那个函数

function Person(){
this.name=name;
}
var child = new Person()
child.constructor = Person//true
Person.prototype.constructor === Person//true

   3.__proto__:任何一个JS对象都包括这个属性,他是用于指向创建他的构造函数的原型对象

child.__proto__ === Person.prototype // true

   4.什么是原型链:由于__proto__是所有对象都有的属性,js里万物皆对象,所以会形成一条__proto__链条,递归访问会到头,最后会到null

var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null

 

 

posted @ 2019-03-03 15:34  进击的白菜  阅读(143)  评论(0编辑  收藏  举报