(二)原型和原型链


一、原型和原型链

在接触原型与原型链中,我产生了以下几个疑问:
1.构造函数、对象等概念是什么?原型对象是什么?
2.不是说只有实例对象有__proto__属性,为什么prototype(原型对象)也有__proto__属性呢?
3.为什么构造函数要单独将一些方法属性提出来,写入prototype中?

1.构造函数

在原型链中,我们有几个概念:构造函数、原型对象、实例对象。
        function Person(){
    
    }
        Person.prototype.age=18;
        Person.prototype.name=function(){
    
    return 'lk'};
        var person = new Person();
         
       
        console.log(Person.prototype);
        console.log(person.__proto__);
        console.log(Person.prototype.constructor);

我们可以看到

  1. 用function创建的叫构造函数,是一个类:Person
  2. 用new关键字声明的是实例对象,通过new Person(),创建了一个Person构造函数的实例对象。
  3. Person.prototype也是一个对象数据类型。
    在这里插入图片描述

2.为什么要一个原型对象?

  //不写在原型对象里
  function Person(){
    
    
        name:'lk';
        sayhi=function(){
    
    return 'hi'};
        }

如果要为Person这个构造函数创建成千上万个实例person1、person2…person10000,那就得不停的创建sayhi函数;那既然都是一样的功能,就写在一个地方,这些Person的实例们去一个地方(原型对象)拿就好啦!
所以我们将一些公共属性与方法写入原型对象里。

3.两个属性:prototype与__proto__

1.每个构造函数都有一个prototype属性,指向自己的原型对象
2.每个对象都有 __proto__属性 ,指向自己构造函数的原型对象(要用没写入构造函数里的方法,所以指向的是构造函数的原型对象)

这下看实例对象、构造函数、原型对象的关系,是不是清楚一些了?
在这里插入图片描述

4.原型链

我们说过,原型对象也是一个对象,具有__proto__属性。所以它也有自己的构造函数(本图是Object构造器/构造函数),原型对象的__proto__属性指向自己的构造函数的原型对象(Object.prototype);而Object.prototype的原型对象是null。
这样通过__proto__属性链接起来的一条路线,就叫做原型链。

在这里插入图片描述

二、new和Object.create的区别

用new和Object.create都可以创建对象,那么为什么要再有另一种方式呢?

1.Object.create的使用

①语法

Object.create(proto,[propertiesObject])

proto:新创建对象的原型对象
propertiesObject:可选。要添加到新对象的可枚举的属性。

②举个简单的栗子看看

<script>
        //自己写的原型对象
        const a = {
    
    
            name:'lk',
            sayhi:function(){
    
    console.log('hi')}
        }
        //创建一个新对象,a是它的原型对象
        const abab = Object.create(a,{
    
    
        height:{
    
    
        writable:true,
        configurable:true,
        value:180
        }
        })
        //看看创建的这个对象
        console.log(abab)
        abab.sayhi()
</script>

更正:下图原型对象a的原型对象应该是Object.prototype,写错了
在这里插入图片描述

2.二者区别

①代码看下

//2.细说区别
        //2.1用字面量创建对象:原型对象是Object
        const b = {
    
    
        name:'lk',
        sayhi:function(){
    
    console.log('hi')}
        }
        console.log(b)
        //2.2用Object.create创建对象,给定一个原型对象为null
        var baby = Object.create(null,{
    
    
            height:{
    
    
                value:18
            }
        })
        console.log(baby)

通过上面原型与原型链的学习,我们可以猜到baby这个对象的原型对象是空。
在这里插入图片描述

通过上面原型与原型链的学习,我们可以猜到baby这个对象的原型对象是空。 我们也可以推测这几个对象(还有1里面的abab对象):
1.abab对象的原型对象是a,a的原型对象是Object.prototype。abab对象可以使用Object.prototype里的属性与方法。在原型链上。
2.用字面量创建的b对象当然也可以使用Object.prototype里的属性与方法。
3.baby对象的原型对象是null,没有什么方法。

试试:

//2.3看看对象abab、b、baby的原型链上的方法toString
        console.log(abab.toString());
        console.log(b.toString());
        console.log(baby.toString());//报错

在这里插入图片描述
当然,我们如果指定原型对象为Object.prototype,和用字面量/new创建的对象就是一模一样的了。

//3.指定原型对象为Object.prototype
        var cdcd =Object.create(Object.prototype);
        console.log(cdcd);
        console.log(cdcd.toString())

在这里插入图片描述
②总结一下
其实他俩的区别大家已经心知肚明了:
Object.create可以指定任意的原型对象,常用于创建一个以空对象为原型对象的实例。

猜你喜欢

转载自blog.csdn.net/qq_42232573/article/details/113116964