第五章 web前端开发工程师--JavaScript高级程序设计 5-7 JavaScript原型

                                                                                      JavaScript原型

 

本节课所讲内容:

  1. JavaScript prototype属性
  2. JavaScript __proto__

                                                                                      主讲教师:Head老师

一. JavaScript 对象创建

我们创建的每个函数都有一个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。通过这两个属性,就可以访问到原型里的属性和方法了。

二. JavaScript __proto__

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

alert(box1.__proto__); //[object Object]

 

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

alert(Box.prototype.isPrototypeOf(box)); //只要实例化对象,即都会指向

 

原型模式的执行流程:

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

 

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

var box1 = new Box();

alert(box1.name); //Lee,原型里的值

box1.name = 'Jack';

alert(box.1name); //Jack,就近原则,

 

var box2 = new Box();

alert(box2.name); //Lee,原型里的值,没有被box1修改

 

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

delete box1.name; //删除属性

alert(box1.name);

 

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

alert(box.hasOwnProperty('name')); //实例里有返回true,否则返回false

 

构造函数实例属性和原型属性示意图

 

 

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

alert('name' in box); //true,存在实例中或原型中

 

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

function isProperty(object, property) { //判断原型中是否存在属性

return !object.hasOwnProperty(property) && (property in object);

}

 

var box = new Box();

alert(isProperty(box, 'name')) //true,如果原型有

 

为了让属性和方法更好的体现封装的效果,并且减少不必要的输入,原型的创建可以使用字面量的方式:

function Box() {};

Box.prototype = { //使用字面量的方式

name : 'Lee',

age : 100,

run : function () {

return this.name + this.age + '运行中...';

}

};

 

原型模式创建对象也有自己的缺点,它省略了构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的。而原型最大的缺点就是它最大的优点,那就是共享。

 

猜你喜欢

转载自blog.csdn.net/wgf5845201314/article/details/92381749