理解 JS 原型

什么有原型?

不管你是用构造函数创建的对象还是用字面量创建的对象都是有原型的

var obj ={}  //推荐
var obj1 =new Object();
//ob1.__proto__ ---->Object.prototype (原型链终端)   

再网上看到这样一张图,感觉对 原型 原型链 描述的非常详细了
在这里我们用构造函数(function Foo () {})创建了两个函数(f1 和 f2)。

_ proto _是个啥呢?是一个指针 指向构造函数的原型对象(也就是指向我们所说的prototype)
在这里f1._ proto _指向的是Foo.prototype

对于prototype 和 construction 他们两个的关系:
每创建一个函数,就会同时创建它的 prototype对象,这个对象也回自动获得construction属性
详细指向图

原型对象的重写:

一个在prototype上的特殊操作来看这段代码 输出结果和你想的是否一致呢?

                            //例1
Person.prototype.name="sunny";

    function Person(){
    //执行new 操作相当于在此处 var this={__proto__:Person.prototype}
    };

    var person=new Person();  //对象已将生成

    //Person.prototype.name="cherry";  //操作1
    //console.log(person.name);  //结果:cherry (可以理解吧~)

    Person.prototype={   //直接改变了存储空间
        name:"cherry"
    }
    console.log(person.name);  //结果:sunny

或许你还是不能理解 那我举一个小例子:

                        //例2
    var obj={say:"hello"};
    var obj1=obj;
        obj={say:"hi"};  //开辟了一个新的空间
        console.log(obj1.say);  //结果:hello

原型 原型链上的增删改查:

对于原型 原型链上的增删改查 一般是不可通过后代来修改,只能通过自己来修改。
直接加值覆盖(=)性的修改是不可以的,仅限于引用值(.)上的修改是可以的。
举一个例子吧:

                            //例3
function Father(){
        this.name="xiaoming";
        this.say={
            say1:"hello word"
        };
    };
    var father=new Father();
    Son.prototype=father;
    function Son(){
        this.name="xiaoxiaoming"
    };
    var son=new Son();
    //son.say="day day up";  //这是一种赋值的修改
    //console.log(father.say);  //{say1: "hello word"}
    //console.log(son.say);  //day day up


    son.say.say2="good good study";  //相当于引用值自己给自己加属性
    console.log(father.say);  //{say1: "hello word", say2: "good good study"}
    console.log(son.say);  //{say1: "hello word", say2: "good good study"}

还是上面这个例子我们改变一下(为 Father 添加一个 monery 属性)

                            //例4
function Father(){
        this.name="xiaoming";
        this.say={
            say1:"hello word"
        };
        this.money=0; //添加一个money属性
    };
    var father=new Father();
    Son.prototype=father;
    function Son(){
        this.name="xiaoxiaoming"
    };

    var son=new Son();
    son.money++;  //相当于 son.money=son.money+1; (son.money 取出来再加1)
    console.log(father.money);  //结果:0
    console.log(son.money);  //结果:1

原型混合 this 指向的问题:

                            //例5
Person.prototype={
        name:"xiaoming",
        sayname:function (){
            console.log(this.name);  //this 指向 谁调用这个方法 this就指向谁  所以指向person
        }
    }

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

    var person=new Person();
    console.log(person.sayname()); //结果:xiaoxiaoming
                            //例6
Person.prototype={
        height:100
    }
    function Person(){
        this.eat=function(){
            this.height ++;
        }
    }
    var person=new Person();
    //person.height=10;
    person.eat();  //这是一个方法 调用方法就是调用函数有()
    //console.log(person.height);  //结果:11  (原因和上面的例5一样 this的指向问题)
    //console.log(Person.prototype.height);  //结果:100

    console.log(person.height);  //结果:101  (相当于上面的例4)
    console.log(Person.prototype.height);  //结果:100

问题来了!

所有的的对象最终都回继承自Object.prototype吗?
这是不正确的 因为还存在一种创建对象的方法 Object.creat (原型)

var obj=Object.create(null);

我们在控制台上查看一下:(obj 里面没有原型)
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_41853863/article/details/81232947