码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript的原型基础1

时间:2015-06-09 06:08:19      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

一、原型的概述:

  我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。

  逻辑上可以这么理解:prototype 通过调用构造函数而创建的那个对象的原型对象。

  使用原型的好处可以让所有对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。

 

 

二、使用原型创建对象

  function Box() {}       //声明一个构造函数,函数体内什么都没有,如果有叫做实例属性,实例方法
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    /*比较一下原型内的方法地址是否一致:*/
    var box1 = new Box();
    var box2 = new Box();
    alert(box1.run == box2.run); //true,方法的引用地址保持一致

  为了更进一步了解构造函数的声明方式和原型模式的声明方式,我们通过图示来了解一下:

    技术分享技术分享

  在原型模式声明中,多了两个属性,这两个属性都是创建对象时自动生成的。

  __proto__属性是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性 constructor。通过这两个属性,就可以访问到原型里的属性和方法了。

  IE 浏览器在脚本访问__proto__会不能识别,火狐和谷歌浏览器及其他某些浏览器均能识别。虽然可以输出,但无法获取内部信息。

  function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    var box1 = new Box();
    var box2 = new Box();
    
    alert(box1.prototype);//这个属性是一个对象,访问不到
    alert(box1.__proto__); //这个属性是一个指针指向prototype原型对象,  打印结果是[object Object]  在IE中结果是undefined
    
    /*
    constructor是构造函数的属性,获取构造函数本身
    作用是被原型指针定位,然后等到构造函数本身,其实就是对象实例对应的原型对象
    */
    alert(box1.constructor);
    
    alert(box1.age);//可以直接访问原型对象中的属性和方法,因为底层会自动调用prototype和__proto__和constructor等属性

  判断一个对象是否指向了该构造函数的原型对象(即判断一个对象实例是不是指向了对象的原型对象)可以使用 isPrototypeOf()方法来测试。

function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    var box1 = new Box();
    var box2 = new Box();
    alert(box1.age);//结果打印出age的值
    alert(Box.prototype.isPrototypeOf(box1)); //只要实例化对象,即都会指向

 

 

 

 

 

三、原型模式的执行流程

  1、先查找构造函数实例里的属性或方法,如果有,立刻返回;
  2、如果构造函数实例里没有,则去它的原型对象里找,如果有,就返回;

  虽然我们可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。

  function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    var box1 = new Box();
    alert(box1.name); //Lee,原型里的值
    box1.name = ‘Jack‘;
    alert(box1.name); //Jack,就近原则,
    var box2 = new Box();
    alert(box2.name); //Lee,原型里的值,没有被 box1 修改

    如果想要 box1 也能在后面继续访问到原型里的值,可以把构造函数里的属性删除即可,具体如下:

  function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    var box1 = new Box();
    alert(box1.name); //Lee,原型里的值
    box1.name = ‘Jack‘;
    alert(box1.name); //Jack,就近原则,
    
    delete box1.name; //删除实例中属性
    alert(box1.name);
    Box.prototype.name = ‘kkk‘//覆盖原型中name属性的值
    alert(box1.name);//结果是kkk
    delete Box.prototype.name;//删除原型中的属性值,之后结果是undefined
    alert(box1.name);

  如何判断属性是在构造函数的实例里,还是在原型里?可以使用 hasOwnProperty()函数来验证:

  function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    var box1 = new Box();
    alert(box1.name); //Lee,原型里的值
    box1.name = ‘Jack‘;
    alert(box1.name); //Jack,就近原则,
    alert(box1.hasOwnProperty(‘name‘));     //判断实例是否存在指定属性   实例里有返回 true,否则返回 false

   技术分享

  in操作符会在通过对象能够访问给定属性时返回 true,无论该属性存在于实例中还是原型中。

  function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    var box1 = new Box();
    alert(‘name‘ in box1); //true,存在实例中或原型

   我们可以通过hasOwnProperty() 方法检测属性是否存在实例中,也可以通过 in 来判断实例或原型中是否存在属性。那么结合这两种方法,可以判断原型中是否存在属性。

  function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    
    
    var box1 = new Box();
    alert(box1.hasOwnProperty(‘name‘)); 
    alert(‘name‘ in box1);
    //如果第一个为false说明实例中没有该属性,而第二个为true说明属性存在原型中
    //如果第一个为true,说明属性存在实例中

   也可以定义一个函数来判段,原理是一样的

  function Box() {} //声明一个构造函数
    Box.prototype.name = ‘Lee‘; //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () { //在原型里添加方法
        return this.name + this.age + ‘运行中...‘;
    };
    function isProperty(object, property) {       //判断原型中是否存在属性
        return !object.hasOwnProperty(property) && (property in object);
    }
    
    var box1 = new Box();
    
    alert(isProperty(box1, ‘name‘)) //true,如果原型有

 

JavaScript的原型基础1

标签:

原文地址:http://www.cnblogs.com/LO-ME/p/4562399.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!