javascript基础-原型对象

1 原型对象

我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,这个对象就是我们所谓的原型对象。

如图,每个我们创建的函数对象都会指向一个自己的原型对象。

- 如果函数作为普通函数调用prototype时没有任何作用(函数名称()调用的方式)
- 当函数以构造函数的形式调用时,他所创建的对象中会有一个隐含的属性指向该构造函数的prototype(原型对象),我们可以通过__proto__来访问该属性。

指向的是同一个原型对象,也就是上面的0x123

我们可以看到,p对象和p2对象指向的是同一个原型对象的地址。

 

不管有几个对象,都是一样的。也就是说,原型对象是一个类创建的所有对象的公共区域,该类的所有对象都可以访问到这个原型对象。所以一般我们将某个类的所有对象公有的内容设置到原型对象里。


可以看出,确实是公共的区域。

通过类设置原型对象,虽然p2对象中并没有name属性,但是公共区域有,在自身区域中找不到后,会去公共区域找。

如果我们在p2对象中设置了name属性,那么输出时自身有,就直接用自身的name了。

如图:


在原型对象中添加函数类型属性:

和普通类型属性一样,也是可以的。

 

使用原型对象,修改44次文档代码:

前一章节我们为了优化内存,将对象中重复的函数类型属性hanshu提取到了全局中,但是会存在一个隐患,那就是一旦协同开发中,其他程序员也使用了hs这名称定义函数的时候,会覆盖我们创建的hs函数,所以我们通过原型对象就可以解决这个问题:

首先实例化Persion让prototype生成并指向,然后向原型对象(prototype)中设置公共属性,这样Persion类的任何一个实例化的对象,都可以访问到公共区域的函数了,而且还避免了将公共函数放到全局的名称污染的问题。

通过类名定义也可以:

该法不必在定义原型对象属性前进行实例化操作,因为我们是通过类名直接定义的。

 -------------------------------------------------------------------------------------------------------------------------

1 关键字in:判断某对象中是否存在相同名称的属性(原型对象中的属性也算)

2 hasOwnProperty()方法,查询自己对象中是否有某个属性

 

我们发现p对象中并没有hasOwnProperty()方法,那么p的原型中有没有呢?

我们发现p的原型对象自身中也是没有hasOwnProperty()方法的,那么该方法到底在哪?

如图:


其实原型对象中也存在原型对象的,就像普通对象中存在原型对象是一样的。

我们可以看到,果然

当然也可以用in关键字查询,更简单:

 

因为关键字in会查询所有的嵌套的对象包括嵌套的原型对象。

注意:原型对象的原型对象,只有这两层,并不是无限嵌套的:

注意:如果在对象中查询是否存在某个属性是,如果第二层原型对象中都不存在的时候,会一直向上查询到Object对象,如果Object对象中还没有,那么返回undefined,注:Object对象是没有原型对象的。

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        function Person(){
        }
        var p=new Person();
        var p2=new Person();
        /* console.log(Person.prototype);//原型对象
        console.log(p.__proto__);//结果与上面一致 */
        


        /* // 通过对象p向原型对象中添加属性
        p.__proto__.name="p";
        // 通过对象p2从原型对象中读取属性
        console.log(p2.__proto__);
        // 结果 p和p2的protp原型对象中属性是公共的区域 */


        /* Person.prototype.name="p";
        console.log(p2.name);//如果p2自身没有name属性,则在公共区域找name属性的值
        // 通过类设置原型对象,虽然p2对象中并没有name属性,
        // 但是公共区域有,在自身区域中找不到后,会去公共区域找。
        p2.name="list";
        console.log(p2.name);
        // 如果我们在p2对象中设置了name属性,那么输出时自身有,就直接用自身的name了。 */
    
    
    // 在原型对象中添加函数类型属性:
    // 公共区域的函数
        Person.prototype.fun=function(){
            alert("p");
        }
        console.log(p2.fun());
        console.log(p.fun());
    
    
    </script>
</head>
<body>
    
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        function Person(name,gender,age){
            this.name =name;
            this.gender =gender;
            this.age =age;
            // this.hanshu=hs;
        }
        function hs(){
            alert(this.name);
        }



        var person1 = new Person("李红","女",20);
        // 通过原型对象定义公共的方法
        person1.__proto__.hanshu=function(){
            alert(this.name)
        }
        console.log(person1.hanshu());
    </script>
</head>
<body>
    
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        function Person(){
           
        }
      
        
        var person1 = new Person();
        // 向构造函数的原型对象中添加name属性
        Person.prototype.name="lihong";
        console.log(person1.name);
        // 通过关键字in检查name属性是否存在p对象中存在
        console.log("name" in person1);//true

        // hasOwnProperty()方法,查询自己对象中是否有某个属性
        console.log(person1.hasOwnProperty("name"));//false
        console.log(person1.__proto__.hasOwnProperty("hasOwnProperty"));//false
        // p的原型对象自身中也是没有hasOwnProperty()方法的


        console.log(person1.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true
        // 在p的原型对象的原型对象中存在该方法。
        // 注意:原型对象的原型对象,只有这两层,并不是无限嵌套的:


        // 可以用in关键字查询,更简单:
        console.log("hasOwnProperty" in person1);//true
        // 因为关键字in会查询所有的嵌套的对象包括嵌套的原型对象。


        // 注意:如果在对象中查询是否存在某个属性是,如果第二层原型对象中都不存在的时候,会一直向上查询到Object对象,如果Object对象中还没有,那么返回undefined,注:Object对象是没有原型对象的。
    </script>
</head>
<body>
    
</body>
</html>

 

posted @ 2021-03-23 10:28  Hhhr  阅读(94)  评论(0编辑  收藏  举报