我们创建的每个函数都有一个原型(原型)属性,这个属性是一个指针,指向一个原型对象,而这个原型对象中拥有的属性和方法可以被所以实例共享。
函数的人(){ } Person.prototype.name=澳峁爬埂? Person.prototype。年龄=29; Person.prototype。sayName=function () { 警报(this.name); }; var person1=新人(); person1.sayName ();//澳峁爬埂? var person2=新人(); person2.sayName ();//澳峁爬埂? 警报(person1。sayName==person2.sayName);//真正的
<强>一、理解原型对象强>
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个原型属性,这个属性指向函数的原型对象。
在默认情况下,所有原型对象都会自动获得一个构造函数(构造函数)属性,这个属性包含一个指向原型属性所在函数的指针。
当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象.ecma - 262第第五版中管这个指针叫[[原型]].
虽然在脚本中没有标准的方式访问[[原型]],但Firefox、Safari和Chrome在每个对象上都支持一个属性__proto__;而在其他实现中,这个属性对脚本则是完全不可见的。
不过,要明确的真正重要的一点就是,这个连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。
以前面使用人构造函数和人。原型创建实例的代码为例,图6 - 1展示了各个对象之间的关系。
在此,人。原型指向了原型对象,而Person.prototype。构造函数又指回了人。
person1和person2都包含一个内部属性,该属性仅仅指向了人。原型;换句话说,它们与构造函数没有直接的关系。
可以调用person1.sayName()。这是通过查找对象属性的过程来实现的。(会先在实例上搜索,如果搜索不到就会继续搜索原型)。
用isPrototypeOf()方法判断实例与原型对象之间的关系
警报(Person.prototype.isPrototypeOf (person1));//正确的 警报(Person.prototype.isPrototypeOf (person2));//真正的
用Object.getPrototypeOf()方法返回实例的原型对象
警报(Object.getPrototypeOf (person1)==Person.prototype);//真正的
使用hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中。
警报(person1.hasOwnProperty("名称"));//错误来着原型
person1.name=癎reg”;
警报(person1.name);//癎reg”——来自实例
警报(person1.hasOwnProperty("名称"));//真正的
<强>二,更简单的原型语法强>
前面例子中每添加一个属性和方法就要敲一遍。原型。为减少不必要的输入,也为了从视觉上更好地封装原型的功能,更常见的做法是用一个包含所有属性和方法的对象字面量来重写整个原型对象。
函数的人(){ } 的人。原型={ 名称:“尼古拉斯”, 年龄:29岁 工作:“软件工程师”, sayName:函数(){ 警报(this.name); }};
在上面的代码中,我们将人。原型设置为等于一个以对象字面量形式创建的新对象。最终结果相同,但有一个例外:构造函数属性不再指向人了。
前面曾经介绍过,每创建一个函数,就会同时创建它的原型对象,这个对象也会自动获得构造函数属性。
var=新人朋友(); 警报(朋友instanceof对象);//正确的 警报(朋友instanceof人);//正确的 alert(朋友。构造函数==人);//错误 alert(朋友。构造函数==对象);//真正的
在此,用instanceof操作符测试对象和人仍然返回真,但构造函数属性则等于对象而不等于人了。
如果构造函数的值真的很重要,可以像下面这样特意将它设置回适当的值。
函数的人(){ } 的人。原型={ 构造函数:人, 名称:“尼古拉斯”, 年龄:29岁 工作:“软件工程师”, sayName:函数(){ 警报(this.name); } };>之前<强>三,原生对象的原型强>
所有原生引用类型(对象,数组、字符串等等)都在其构造函数的原型上定义了方法。
分析javascript原型及原型链