理解原型对象
原型模式
我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象。
而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
按照字面意思来理解,那么prototype就是通过调用构造函数而创建的那个对象实例的原型对象,使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为改函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获取一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针.
html lang="en"> <head> <meta charset="UTF-8"> <title>JS构造函数</title> </head> <body> </body> <script> /************************构造函数模式**************************/
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var person1 = new Person('Nicholas',29,"Software Engineer"); var person2 = new Person('Greg',27,"Doctor"); person2.sayName(); /*****原型模式**********************************************************************/ function Person(){ } Person.prototype.name = 'Nicholas'; Person.prototype.age = 29; Person.prototype.sayName = function(){ alert(this.name); };
/*************************isPrototypeOf方法***************************/ //var person1 = new Person(); //alert(Person.prototype.isPrototypeOf(person1)); // isPrototypeOf()方法来确定对象之间是否存在原型关系 //ECM5增加一个新的方法,Object.getPrototypeOf() //alert(Object.getPrototypeOf(person1)==Person.prototype); //true //Object.getPrototypeOf(person1) 返回的对象实际就是这个对象的原型。 //person1.sayName(); /*******hasOwnProperty()方法可以检测一个属性是存在事实例中,还是存在于原型中*********************/ var person1 = new Person(); var person2 = new Person(); alert(person1.hasOwnProperty("name")); //false person1.name="Greg"; alert( person1.name); //"Greg"---来自实例 alert(person1.hasOwnProperty("name")); // true alert(person2.name); //Nicholas----来自原型 alert(person2.hasOwnProperty("name")); // false /***判断一个属性是否在原型中***/ function hasPrototypeProperty(object,name){ return !object.hasOwnProperty(name) && (name in object); } </script> </html>
2,探究原型对象从何而来
问题:既然原型对象也是一个对象,那么其又是由那个类实例化而来呢?
记住:所有的原型对象在实例化时都会自动执行以下代码
(构造函数名称.prototype) = new Object();
所以,所有·的原型对象都是Object类的实例化,在JS中,Object是所有类的基类。
所以原型对象会自动继承Object类中所有属性和方法。
3,原生对象的原型
原生模式的重要性不仅体现在创建自定义类型方面,就连所有原生的引用类型,都是采用这种模式创建的。所有原生引用类型(object ,Array,String等等)都在其构造函数的原型上定义了方法。
例如:在Array.prototype中可以找到sort()方法,而在String.prototype中可以找到substring方法,如下所示:
alert(typeof Array.prototype.sort) //function
alert(typeof String.prototype.substring) //function
痛过原生对象的原型,不仅可以取得所有默认方法的引用,而且也可以定义新方法。可以像修改自定义对象的原型一样修改原生对象的原型。可以随时添加方法。下面代码就给基本包装类型String添加了一个名为startWith()方法。
String.prototype.startsWith = function (text){ return this.indexOf(text)==0; } var msg = "Hello World"; alert(msg.startsWith("Hello") ); //true