ECMAScriptjavascript原型Prototype

在javaScript创建对象同一和平遭遇涉嫌了:用构造函数创建对象存在一个问题就平构造函数的不同实例的同方法是未同等的,因此我们就此原型把构造函数中公共的性质和措施提取出来进行包装,达到为具备实例共享的目的。

连下进一步介绍javaScript原型。

一样、javaScript原型机制

1、函数和原型的涉

js中创造一个函数,就会自动创建一个prototype属性,这个特性指向函数的原型对象,并且原型对象会自动获取一个constructor(构造函数)属性,指为该函数。

比喻:以前面的原型模式创建对象为条例说明

ECMAScript 1ECMAScript 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。

ECMAScript 3

希冀1部数、实例与原型的涉及(图来在JS高程)

大概一句子话虽是:Person.prototype.constructor指向Person,可以在浏览器中测试一下。

ECMAScript 4

2、实例与原型的关联

经构造函数创建一个实例,该实例之中拿涵盖一个特性(指针),指向构造函数的原型对象。

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

Note:[[Prototype]]接连是存在吃实例和构造函数的原型之间,而休是存在实例与构造函数之间。

至于这个指针,ECMA-262中受[[Prototype]],没有标准的不二法门访[[Prototype]],但Firefox、Safari和Chrome在每个对象及都支持一个性质__protp__,而以外实现着,这个特性对剧本不可见。

ECMAScript 5

3、原型链

实例有和好之性能和章程,而原型封装了颇具实例共享的特性和措施,那这种共享是透过什么措施实现之也?答案是原型链。

当要拜实例的属性时,解析器会执行同一赖搜索。首先由实例对象开始,如果在实例中找到了这特性,则回该属性的值;重点是要没有找到的话,则继续搜寻[[Prototype]]指南针指向的原型对象,在原型对象吃查找该属性,如果找到,则归该属性之价。所以经这种措施多单实例就能同享保存在原型中之习性和方式。这吗是js的原型链。

Note:理解了原型链,很自然就是能够了解几只问题。

a、给实例添加一个同原型中同名的特性,就见面将那个屏蔽。因为找原型链时在实例中虽能够找到然后就是归了,根本到无了原型。

b、可以通过实例爬原型链访问原型中的价值,但可休可知经过实例更写原型中之价值。同理。

c、原型的动态性,在原型上增产属性或艺术能立即从实例反应出来。

老二、原型相关的法子介绍

1、isPrototypeOf()方法

虽实例的[[Prototype]]属性无法访问的,我们得以经过isPrototypeOf()方法来认可原型和实例之间的干。这个法吧是立在原型的角度来检测原型是未是有实例的原型。A.isPrototypeOf(B),如果A的B的原型返回true,否则回false。

举例:因为Person的有限单实例lxy和personA内部还起一个[[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>

结果:

ECMAScript 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()方法,收获有实例属性,无论其是不是只是枚举。

ECMAScript 7ECMAScript 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了。

ECMAScript 9ECMAScript 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。

ECMAScript 11ECMAScript 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发出题目欢迎和己谈谈,共同进步。