javascript原型Prototype

javaScript创立对象一文中涉嫌过:用构造函数成立对象存在三个标题即一致构造函数的差异实例的如出一辙形式是不均等的,所以大家用原型把构造函数中公共的性质和章程提取出来实行打包,达到让全部实例共享的目标。

接下去进一步介绍javaScript原型。

① 、javaScript原型机制

① 、函数与原型的涉及

js中开创二个函数,就会活动创设3个prototype属性,那脾个性指向函数的原型对象,并且原型对象会自动获得一个constructor(构造函数)属性,指向该函数。

比喻:今后面包车型大巴原型方式制造对象为例说明

图片 1图片 2

<script type="text/javascript">
function Person(){

}
Person.prototype.name="lxy";
Person.prototype.age=22;
Person.prototype.job="Software Engineer";
Person.prototype.sayName=function(){
    alert(this.name);
}

     var lxy=new Person();
     lxy.sayName();
     var personA=new Person();
     personA.sayName();
     alert(lxy.sayName()==personA.sayName());//true
</script>

View Code

Person对象和Person对象的原型之间的关联如下图1。

图片 3

图1函数、实例与原型的关系(图来着JS高程)

一句话来说一句话就是:Person.prototype.constructor指向Person,能够在浏览器中测试一下。

图片 4

② 、实例与原型的涉嫌

经过构造函数创建多个实例,该实例之准将涵盖叁本质量(指针),指向构造函数的原型对象。

举例来说:Person构造函数的实例Person1和Person2的[[Prototype]]质量都针对Person的原型。如图1所示。

Note:[[Prototype]]总是是存在于实例和构造函数的原型之间,而不是存在实例与构造函数之间。

至于这么些指针,ECMA-262中叫[[Prototype]],没有正经的法门访问[[Prototype]],但Firefox、Safari和Chrome在每一种对象上都帮助多个属性__protp__,而在此外完结中,那个个性对剧本不可知。

图片 5

3、原型链

实例有投机的属性和章程,而原型封装了富有实例共享的质量和艺术,这那种共享是通过如何艺术贯彻的呢?答案是原型链。

当要访问实例的习性时,解析器会执行2回搜索。首先从实例对象开头,若是在实例中找到了那本天性,则赶回该属性的值;重点是一旦没有找到的话,则继续寻找[[Prototype]]指南针指向的原型对象,在原型对象中查找该属性,假诺找到,则赶回该属性的值。所以经过那种方式多少个实例就能共享保存在原型中的属性和方法。这也是js的原型链。

Note:精晓了原型链,很自然就能明白多少个难点。

a、给实例添加贰个与原型中同名的习性,就会将其屏蔽。因为搜索原型链时在实例中就能找到然后就回到了,根本到持续原型。

b、能够透超过实际例爬原型链访问原型中的值,但却不能够通超过实际例重写原型中的值。同理。

c、原型的动态性,在原型上新增属性或措施能马上从实例反应出来。

贰 、原型相关的法子介绍

1、isPrototypeOf()方法

固然实例的[[Prototype]]品质不恐怕访问的,大家得以由此isPrototypeOf()方法来确认原型和实例之间的关联。这些法子呢是站在原型的角度来检查和测试原型是或不是有个别实例的原型。A.isPrototypeOf(B),如若A的B的原型重临true,不然重临false。

比方:因为Person的多少个实例lxy和personA内部都有1个[[Prototype]]个性指向Person.prototype。所以isPrototypeOf方法会重临true。

<script type="text/javascript">
    function Person(){

    }
    Person.prototype.name="lxy";
    Person.prototype.age=22;
    Person.prototype.job="Software Engineer";
    Person.prototype.sayName=function(){
        alert(this.name);
    }

    var lxy=new Person();
    var personA=new Person();
    console.log(Person.prototype.isPrototypeOf(lxy)); //true
    console.log(Person.prototype.isPrototypeOf(personA)); //true
</script>

2、Object.getPrototypeOf()方法

本条形式是ECMAScript 5中新增的,再次回到实例的[[Prototype]]值。

那些措施是那三个实用的,因为它是在Object上落到实处的。所以把任何实例扔给Object,它都能获得实例的原型。

举例

<script type="text/javascript">
    function Person(){

    }
    Person.prototype.name="lxy";
    Person.prototype.age=22;
    Person.prototype.job="Software Engineer";
    Person.prototype.sayName=function(){
        alert(this.name);
    }

    var lxy=new Person();
    console.log(Object.getPrototypeOf(lxy));
    console.log(Object.getPrototypeOf(lxy)==Person.prototype); //true
    console.log(Object.getPrototypeOf(lxy).age);//22
</script>

结果:

图片 6

3、hasOwnPrototype()方法

其一措施用于检查和测试有些属性是还是不是确实存在于实例中。是回到ture,不然重返false。

就像是我们温馨有一部分能源和技能,但是也得以从大人那里拿走部分能源和技巧,比如看起来您有套别墅,不过你要精晓如何是你确实属于您本身的,哪些是父母给你的。

举例来说:比如自身一出生父母就给笔者个名字lxy,那时候小编用hasOwnPrototype()方法检查和测试那几个”name”属性是不真是自身的,就会回到false。

新兴自家自身改了个名字starof,再用hasOwnPrototype()方法检查和测试,那时就会回来true。

再后来本人不想用这几个名字了,笔者就把它delete掉了,用回了自笔者父母给的名字。那时候再用hasOwnPrototype()方法检测那个”name”属性是否自己要好的,就会回去false。

其一一波三折的故事代码如下:

<script type="text/javascript">
    function Person(){

    }
    Person.prototype.name="lxy";

    var lxy=new Person();
    console.log(lxy.name);
    console.log(lxy.hasOwnProperty("name"));  //false 
    lxy.name="starof";//通过重写屏蔽原型属性name,所以这个name就变成了实例属性
    console.log(lxy.name);
    console.log(lxy.hasOwnProperty("name"));  //true
    delete lxy.name;
    console.log(lxy.name);
    console.log(lxy.hasOwnProperty("name"));  //false
</script>

4、in操作符,for-in循环,Object的keys()和getOwnPropertyNames()

in操作符在通过对象能够访问质量时回来true,无论该属性是实例属性照旧原型属性。

for-in循环,再次回到全数能够透过对象访问的,可枚举的性质。即包蕴实例属性也囊括原型属性。

遮掩了原型中不可胜言的性质的实例属性也会在for-in循环中回到,因为依据规定,全数开发职员定义的属性都是可枚举的——唯有在IE8及更早版本中分裂。

Object.keys()方法,取得实例上所有可枚举的实例属性。该措施接收一个实例作为参数,重回三个暗含全部可枚举属性的字符串数组。

Object.getOwnPropertyNames()方法,得到全体实例属性,无论它是或不是可枚举。

图片 7图片 8

<script type="text/javascript">
    function Person(){

    }
    Person.prototype.name="lxy";
    Person.prototype.age=22;
    Person.prototype.job="Software Engineer";
    Person.prototype.sayName=function(){
        alert(this.name);
    }

    var lxy=new Person();
    //in
    console.log("name" in lxy);//in实例可访问的属性
    //for-in
    for(var prop in lxy){
        console.log(prop);
    }//for-in列出所有可访问的,可枚举的属性
    //Object.keys
    var keys=Object.keys(Person.prototype);
    console.log(keys);//Person的原型的所有可枚举属性
    var keys=Object.keys(lxy);
    console.log(keys);//lxy现在没有实例属性,所以keys为空
    lxy.name="lxy";
    var keys=Object.keys(lxy);
    console.log(keys);
    //Object.getOwnPrototypeNames
    console.log(Object.getOwnPropertyNames(lxy));//得到所有实例属性
</script>

View Code

三 、原型语法

率先种:每添加二个属性和章程,都间接在原型上加。

<script type="text/javascript">
    function Person(){
    }
    Person.prototype.name="lxy";
    Person.prototype.age=22;
    Person.prototype.job="Software Engineer";
    Person.prototype.sayName=function(){
        alert(this.name);
    }

    var lxy=new Person();
</script>

其次种:对象字面量的办法

<script>
    function Person(){
    }
    Person.prototype={
        name:"lxy",
        age: 22,
        job:"Software Engineer",
        sayName:function(){
            alert(this.name);
        }
    };
    var lxy=new Person();
</script>

其次种语法相比简单,少写几行代码,但是有几许要专注,字面量情势,完全重写了prototype属性,所以constructor不再指向Person,而是Object了。

图片 9图片 10

<script>
    function Person(){
    }
    Person.prototype={
        name:"lxy",
        age: 22,
        job:"Software Engineer",
        sayName:function(){
            alert(this.name);
        }
    };
    var lxy=new Person();

    console.log(lxy.constructor==Person);//false
    console.log(lxy.constructor==Object);//true

</script>

View Code

若是constructor很主要,可手动设置为Person,如下。

<script>
    function Person(){
    }
    Person.prototype={
        constructor:Person,
        name:"lxy",
        age: 22,
        job:"Software Engineer",
        sayName:function(){
            alert(this.name);
        }
    };
    var lxy=new Person();

    console.log(lxy.constructor==Person);//true
    console.log(lxy.constructor==Object);//false
</script>

 可是那般写会造成constructor的[[Enumerable]]特点被置为true。因为开发职员定义的习性都以可枚举的。

假要是包容ECMAScript5的JS引擎可采取Object.definePrototype。

图片 11图片 12

<script>
    function Person(){
    }
    Person.prototype={
        name:"lxy",
        age: 22,
        job:"Software Engineer",
        sayName:function(){
            alert(this.name);
        }
    };
    //重设构造函数,只适用于ECMAScript5兼容的浏览器
    Object.defineProperty(Person.prototype,"constructor",{
        enumerable:false,
    value:Person
    })

    var lxy=new Person();

    console.log(lxy.constructor==Person);//true
    console.log(lxy.constructor==Object);//false
</script>

View Code

 

正文小编starof,因知识本人在转变,小编也在频频学习成长,小说内容也不安时更新,为幸免误导读者,方便追根溯源,请各位转发表明出处:http://www.cnblogs.com/starof/p/4904929.html有标题欢迎与自己谈谈,共同提升。