JavaScript-封装
原型(protytype)对象
javascript通过构造函数生成新对象,因此,构造函数可以视为实例对像的模板,实例对象的属性和方法可以定义在构造函数内部.
//一般实例化对象的操作 function create_obj(name){ this.name = name; this.color = 'white'; } var cat = new create_obj('co'); cat.name // co cat.color //white
javascript还可以用prototype对象来定义实例对象的方法,且定义在它上面的属性与方法 ,能被所有实例对象共享,一但修改prototype定义的属性或方法,实例对象也会跟着修改. 总而言之,prototype对象的作用,就是定义所有实例对象共享的属性和方法, 所以它也被称为实例对象的原型,而实例对象可以视作从prototype对象衍生出来的。
function create_obj(name){ this.name = name; } create_obj.prototype.color = "小白"; create_obj.prototype.eat = function(){ console.log(this.name + '吃东西' + '他是' + this.color); }; var cat1 = new create_obj('老大'); var cat2 = new create_obj('老二'); cat1.eat(); //老大吃东西他是小白 cat2.eat(); //老二吃东西他是小白
原型链
javascript所有对象都有构造函数,
而所有构造函数都有prototype发生,
所以所有对象都有自己的prototype原型对象.
因此,一个对象的属性和方法,有可能定义它自身上面,
也有可能定义在它的原型对象上面.
由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain).
比如,a对象是b对象的原型,b对象是c对象的原型,以此类推。因为追根溯源,
最源头的对象都是从Object构造函数生成(使用new Object()命令),
所以如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype。
Object.prototype的原型是没有任何属性和方法的null
“原型链”的作用在于,当读取对象的某个属性时,
JavaScript引擎先寻找对象本身的属性,
如果找不到,就到它的原型去找,
如果还是找不到,就到原型的原型去找。
以此类推,如果直到最顶层的Object.prototype还是找不到,
则返回undefined。
function MyArray (){} MyArray.prototype = new Array(); var mine = new MyArray(); mine.push(1, 2, 3); mine.length // 3 mine instanceof Array // true // 等同于 Array in [ MyArray.prototype.constructor, // 即MyArray Array.prototype.constructor, // 即Array Object.prototype.constructor // 即Object ]
上面代码的mine是MyArray的实例对象, 由于MyArray的prototype属性指向一个数组, 使得mine可以调用数组方法(这些方法其实定义在数组的prototype对象上面)。 至于最后那行instanceof表达式,我们知道instanceof运算符用来比较一个对象 是否为某个构造函数的实例,最后一行表示mine为Array的实例
constructor属性
prototype对象有一个constructor属性,默认指向prototype对象所在的构造 函数。可以被所有实例对象继承。
var a = new Array(); a.hasOwnProperty('constructor'); //false a.constructor === Array.prototype.constructor //true
上面代码表示a是构造函数Array的实例对象,但是a自身没有contructor属性。 该属性其实是读取原型链上面Array.prototype.contructor属性。 可以用来分辨prototype对象到底定义在哪个构造函数上面。如下
function FOO(){} FOO.prototype.contructor === FOO; // true
Object.getPrototypeOf方法
getPrototypeOf方法返回一个对象的原型。
Object.getPrototypeOf({}) === Object.prototype //true function F(){} Object.getPrototypeOf(F) === Function.prototype //true var f = new F(); Object.getPrototypeOf(f) === F.prototype // true
Object.create方法
Object对象的create方法用于生成新的对像。 它接受一个原型对象作为参数,返回一个新对象, 后者完全继承前者的属性。
var o1 = {p:1}; var o2 = Object.create(o1); console.log(o2.p); //1
如果老式浏览器不支持Object.create方法,可以用下面代码代替
if(typeof Object.create !== 'function'){ Object.create = function(o){ function F(){} F.prototype = o; return new F(); } } //Object.create方法实质是新建一个构造函数F, 然后让F的prototype属性指向作为原型的对象o, 最后返回一个F的实例,从而实现让实例继承o的属性。
Object.create方法使用的时候,必须提供对象原型,否则会报错.
Object.create方法可以接受两个参数,第一个是对象的原型, 第二个是描述属性的attributes对象.
//Object.create(prototype,propDescObj) var o = Object.create(Object.prototype,{ p1:{value:123, enumerable:true}, p2:{value:"abc", enumerable:true}, }); o.p1; //123 o.p2; //"abc"
isPrototypeOf方法
该方法用来判断一个对象是否是另一个对象的原型.
var o1 = {}; var o2 = Object.create(o1); var o3 = Object.create(o2); console.log(o2.isPrototypeOf(o3));//true console.log(o1.isPrototypeOf(o1));//true