网站备案点不进去,扶沟县网站开发,wordpress网易插件怎么用,电商网站建设成本我们创建的每个函数都有一个prototype(原型)属性#xff0c;这个属性是一个指针#xff0c;指向一个对象#xff0c;它的用途是包含可以有特定类型的所有实例共享的属性和方法。 prototype就是通过构造函数而创建的那个对象的原型对象。使用原型的好处就是可以让所有对象实例… 我们创建的每个函数都有一个prototype(原型)属性这个属性是一个指针指向一个对象它的用途是包含可以有特定类型的所有实例共享的属性和方法。 prototype就是通过构造函数而创建的那个对象的原型对象。使用原型的好处就是可以让所有对象实例共享它所包含的属性和方法 。 function Person() {
}
Person.prototype.name zxj;
Person.prototype.age 29;
Person.prototype.job Software Engineer;
Person.prototype.sayName function () {alert(this.name);
}
var person1 new Person();
person1.sayName(); //zxj
var person2 new Person();
person2.sayName(); //zxj 1、理解原型对象 无论什么时候只要创建了一个新函数ECMAScript就会根据一组特定的规则为该函数创建一个prototype属性这个属性指向函数的原型对象。在默认情况下所有原型对象都会自动获得一个constructor构造函数属性这个属性包含一个指向prototype属性所在函数的指针。就拿前面的例子Person.prototype.constructor指向Person。而通过这个构造函数我们还可以继续为原型对象添加其他属性和方法。 创建了自定义指针之后其原型对象默认只会取得constructor属性至于其它方法都会从Object对象继承而来。当调用构造函数创建一个新实例之后该实例的内部将包括一个指针内部属性指向构造函数的原型对象。ECMA-262第5版中管这个叫[[Prototype]]。 要明确一点的就是这个连接存在于实例和构造函数的原型对象之间而不是存在于实例和构造函数之间。 以前面使用的Person构造函数和Person.prototype创建实例的代码为例如下图 上图展示了Person构造函数、Person的原型属性以及Person现有的两个实例之间的关系。在此Person.prototype指向了原型对象而Person.prototype.constructor又指回了Person。原型对象中除了包含constructor属性之外还包括后来添加的其他属性。Person的每一个实例——person1和person2都包含一个内部属性该属性仅仅指向Person.prototype。换句话说它们与构造函数没有直接的联系。此外要格外注意的是虽然这两个实例都不包含属性和方法但我们却可以调用person1.sayName()。这是通过查找对象属性的过程来实现的。 虽然我们无法访问到[[Prototype]]但可以通过isPrototypeOf()方法来确定对象之间是否存在这种关系。从本质上讲如果[[Prototype]]指向调用isPrototypeOf()方法的对象Person.prototype,那么这个方法就会返回true。 alert(Person.prorotype.isPrototypeOf(person1)); //true
alert(Person.prorotype.isPrototypeOf(person2)); //true 每当代码要读取某个对象的属性时都会进行一次搜索搜索目标是具有给定名称的属性。搜索当然先从对象实例的本身开始如果找到了就可以返回该值了如果找不到则会去指针所指向的原型对象中去查找在原型对象中找到了就可以顺利返回该值。而这正是多个对象实例共享原型所保存的属性和方法的基本原理。 虽然可以通过对象实例访问到保存在原型中的值但不能通过对象实例重写原型中的值。根据查找原理如果找到了实例中的值就不会再去查找原型对象中的值。代码如下所示 function Person() {
}
Person.prototype.name zxj;
Person.prototype.age 29;
Person.prototype.job Software Engineer;
Person.sayName function () {alert(this.name);
}
var person1 new Person();
var person2 new Person();
person1.name Greg;
alert(person1.name); //Greg 来自实例
alert(person2.name); //zxj 来自原型
delete person1.name; //删除实例中的name属性
alert(person1.name); //zxj 来自原型 使用hasOwnPeoperty()方法可以检测一个属性是否存在于实例中还是存在原型中这个方法(它是从Object继承来的)只在给定属性存在域对象实例中时才返回true。 function Person() {
}
Person.prototype.name zxj;
Person.prototype.age 29;
Person.prototype.job Software Engineer;
Person.sayName function () {alert(this.name);
}
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); //zxj 来自原型
alert(person2.hasOwnProperty(name)); //false
delete person1.name;
alert(person1.name); //zxj 来自原型
alert(person1.hasOwnProperty(name)); //false 2、原型与in操作符 有两种方式使用in操作符一、单独使用二、for-in中使用。 功能会在通过对象能够访问给定属性时返回true无论是在对象实例中或是原型中。 function Person() {
}
Person.prototype.name zxj;
Person.prototype.age 29;
Person.prototype.job Software Engineer;
Person.sayName function () {alert(this.name);
}
var person1 new Person();
var person2 new Person();alert(person1.hasOwnProperty(name)); //false
alert(name in person1); //trueperson1.name Greg;alert(person1.name); //Greg 来自实例
alert(person1.hasOwnProperty(name)); //true
alert(name in person1); //truealert(person2.name); //zxj 来自原型
alert(person2.hasOwnProperty(name)); //false
alert(name in person2); //truedelete person1.name;
alert(person1.name); //zxj 来自原型
alert(person1.hasOwnProperty(name)); //false
alert(name in person1); //truealert(person1.hasOwnProperty(qqqq)); //false
alert(qqqq in person1); //false 同时使用hasOwnProperty()和in操作符可以判断出该属性到底是存在对象实例中还是存在与原型中。 使用for-in循环时返回的是所有能够通过对象访问的可枚举(enumerated)属性其中即包括存在与实例中的属性也包括存在与原型中的属性。根据规定开发人员定义的属性都是可枚举的——IE8及更早版本除。 var o {toString: function () {return My Object;}
}
for (var prop in o) {if (prop toString) {alert(Found toString); //在IE中不会显示(IE9(未测试)和IE10(已测试)可用)}
} 3、更简单的原型语法 我们可以用一个包含属性和方法的对象字面量重写整个原型对象。 function Person(){
}Person.peototype{name:zxj,age:29,job:Software Engineer,sayName:function(){alert(this.name);}
}; 结果是与先前的相同但有一个是不同的contrcutor属性不再指向Person了。我们曾经介绍过没创建一个函数就会同时创建它的prototype对象这个对象也会自动获得constructor属性。而我们这样写本质上是完全重写了默认的prototype对象因此constructor属性也就变成了新对象的constructor属性指向Object构造函数不再指向Person函数。 当然我可以将它特意设置成适当的值 function Person() {
}Person.prototype {constructor: Person,name: zxj,age: 29,sayName: function () {alert(this.name);}
}; 以上代码特意包含了一个constructor属性并将它的值设置为Person从而确保了通过该属性能够访问到适当的值。 注意以这种方式重设constructor属性会导致它的[[Enumerable]]特性被设置为true。默认情况下constructor属性是不可枚举的。因此如果你使用兼容ECMASCript5的JavaScript引擎可以试一试Object.definePropety()。 function Person() {
}Person.prototype {constructor: Person,name: zxj,age: 29,sayName: function () {alert(this.name);}
};Object.defineProperty(Person.prototype,constructor,{enumerable:false,value:Person
}); 4、原型的动态性 由于在原型中查找值的过程是一次搜索因此我们对原型对象所做的任何修改都能够立即从实例上反映出来——即使是先创建了实例后修改原型也照样可以如下所示 function Person() {
}var friend new Person();Person.prototype.sayHi function () {alert(hi);
}friend.sayHi(); //hi 尽管可以随时为原型添加属性和方法但如果我们重写了整个原型对象那么情况就不一样了。我们知道调用构造函数时会为实例添加一个指向最初原型的[[Prototype]]指针而把原型修改为另一个对象就等于切断了构造函数与最初原型之间的联系。一定要记住实例中的指针仅仅指向原型而不是构造函数。如下例子 function Person() {
}var friend new Person();Person.prototype {constructor: Person,name: zxj,age: 29,job: Software Engineer,sayName: function () {alert(this.name);}
};friend.sayName(); //error 找不到该方法 、 5、原生对象的原型 原型模式的重要性不仅体现在创建自定义类型方面就连所有原生的引用类型都是采用这种模式创建的。所有引用类型Object、Array、String等等都在构造函数的原型上定义了方法。例如在Array.prototype中可以找到sort()方法而在String.prototype中可以找到substring()方法如下所示 alert(typeof Array.prototype.sort); //function
alert(typeof String.prototype.substring); //function 通过原生对象的原型不仅可以取得所有默认方法的引用而且也可以定义新方法。如下所示 String.prototype.startWith function (text) {return this.indexOf(text) 0;
}var msg Hello World;alert(msg.startWith(Hello)); //true 6、原型对象的问题 原型模式的缺点。首先它省略了为构造函数传递初始化参数这一环节结果所有的实例在默认情况下都取得了相同的值。原型模式最大的问题是由其共享的本性所导致的。 Person.prototype {constructor: Person,name: zxj,age: 29,job: Software Engineer,friends: [saly, geil],sayName: function () {alert(this.name);}
};var person1 new Person();
var person2 new Person();person1.friends.push(van);alert(person1.friends); //saly,geil,van
alert(person2.friends); //saly,geil,vanalert(person1.friends person2.friends) //问题出来了person1结交了新朋友意味着person2也必须结交这个朋友 我们可以看到当一个对象想获取独有的操作时原型模式的共享就是最大的阻碍。 转载于:https://www.cnblogs.com/zxj159/archive/2013/05/20/3089513.html