面向对象编程(1)
/ / ECMA-262定义一个对象作为一个集合的无序的属性,这些属性可以包含基本的价值观,对象或函数
理解对象,最简单的方法是创建对象的实例,然后为它添加属性和方法。
var =新对象();
person.name =徐磊;
person.age =23;
person.job =前端工程师;
person.sayname =函数(){
警报(这个名字);
}
也可以写这个
var
名称:徐蕾
年龄:23岁,
工作:前端项目
sayname:函数(){
警报(这个名字)
}
}
属性类型:访问数据属性并访问其属性
1,数据属性,描述它们行为的4个特性
/ / {配置}:表明我们是否可以删除的属性,使我们可以重新定义属性,我们是否可以修改属性的属性,或者我们是否可以修改属性访问器的属性,和默认值为true。
/ / {枚举}:指示是否能够返还财产的,与真正的默认值
可写}:指示是否可以修改属性,默认值为真。
{值}:包含此属性的数据值。默认值未定义。
var
名称:旭蕾
}
/ /在这里创建了一个个人目标,价值是Xulei
修改默认的/特征属性,您必须使用ecmascript5 object.defineproperty(对象,属性的属性名称,对象描述符)
/ /描述符对象必须是可配置的,可枚举,可值
var庇隆{ }
object.defineproperty(庇隆,名字
可写的:不能修改假属性
价值:Xu Lei徐磊
});
警报(庇隆的名字); / /徐雷-徐磊
peron.name =徐雷;
警报(庇隆的名字); / /徐雷-徐磊
在非严格模式分配中忽略了上述操作,如果在严格模式下抛出异常
属性定义为 /不可配置时不能将其更改为可配置的。
/ /在大多数情况下是没有必要使用object.defineproperty()提供这些先进的功能的方法。但它的理解很有用。
建议读者 / /不在IE8中使用这个方法。
2,访问它的属性,有4个特性
/ / {配置}:表明我们是否可以删除的属性,使我们可以重新定义属性,我们是否可以修改属性的属性,或者我们是否可以修改属性访问器的属性,和默认值为true。
/ / {枚举}:指示是否能够返还财产的,与真正的默认值
get }:在读取时调用未定义函数的默认值。
设置属性时调用的函数的默认值。
var图书{
_year:2004,
版本:1
}
Object.defineProperty(书、年
获取:函数(){
这_year返回;
},
设置:函数(值){
如果(值> 2004){
这_year =价值;
this.edition + = value-2004;
}
}
});
书,一年= 2005;
警报(图书版);2
创建对象
1,使用构造函数作为函数
功能人(姓名,年龄,工作){
这个名字=名字;
这个年龄=年龄;
这个,工作=工作;
这个sayname =函数(){
警报(这个名字);
}
}
作为构造函数
无功的人=新的人(徐磊
person.sayname();
作为普通函数使用
人(xulei2
Window.sayName();
在另一个对象的作用域中调用。
新对象();
person.call(O,xulei3
O.sayName();
另一款:
1,理解原型对象
2、原型和运算符
3,更简单的原型语法
4/原型的动力学
5,本机对象的原型
6,原型对象的问题
1,每当创建一个函数时,它将根据一组特定规则为函数创建一个原型属性。此属性指向函数的原型对象。
默认情况下,所有原型对象都会自动获得构造函数(构造函数)属性,这个属性包含指向函数原型属性的指针。
功能人(){
}
/ / person.prototype.constructor点人
在创建自定义构造函数之后,默认的原型对象只获得构造函数属性,因为其他方法是从对象继承的。
在创建一个新实例时,实例内部包含指向构造函数的指针(内部属性)原型对象。
在Firefox,Safari,Chrome / /在每个对象支持_proto_属性访问
新的人();
警报(person.prototype.isprototypeof(P1))
警报(Object.getPrototypeOf(P1)= =人。原型)
虽然可以通过存储在原型值中的对象实例来访问,但不可以重写原型对象实例中的值。
在相同名称的实例中,属性和原型的名称,然后我们将在示例中创建属性,这个属性将屏蔽原型。Eg:
功能人(){
}
人。原型。名称=琥珀;
原型,年龄= 23;
人。原型。作业=软件工程师;
人的原型。sayname =函数(){
警报(这个名字)
}
VaR甲=新的人();
var 2 =新的人();
甲。名称=琥珀。许;
警报(甲的名字); / / amber.xu --从一个实例
警报(2名); / /琥珀--从原型
删除person1.name;
警报(甲的名字); / /琥珀--从原型
对hasownproperty / 使用/()方法可以检测一个属性是在实例或原型的存在,这种方法(从对象)
只有在对象实例中的给定属性中,才会返回true。
功能人(){
}
人。原型。名称=琥珀;
原型,年龄= 23;
人。原型。作业=软件工程师;
人的原型。sayname =函数(){
警报(这个名字)
}
VaR甲=新的人();
var 2 =新的人();
警报(person1.hasownproperty(名称)); / /假来自实例
警报(person2.hasownproperty(名称)); / /假来自实例
甲。名称=琥珀。许;
警报(甲的名字);
警报(person1.hasownproperty(名称)); / /真的来自一个实例
删除person1.name;
警报(甲的名字);
警报(person1.hasownproperty(名称)); / /假来自原型
2、原型和运算符
有使用 / /两种方式,一是单独使用,用于for-in.when单独使用,在操作时返回真的对象能够访问一个给定的属性
无论何时,当属性来自原型或实例时
功能人(){
}
人。原型。名称=琥珀;
原型,年龄= 23;
人。原型。作业=软件工程师;
人的原型。sayname =函数(){
警报(这个名字)
}
VaR甲=新的人();
var 2 =新的人();
警报(名在甲); / /真实的原型
警报(名在2); / /真实的原型
警报(高度在甲); / /假
因此,您可以封装一个函数(是否将属性赋予给定的对象原型)。
功能hasprototypeproperty(对象的名字){
返回!Object.hasOwnProperty(名字)(名字对象);
}
警报(---------------------------------- );
警报(hasprototypeproperty(甲,名字)); / /真的
甲。名称=张三;
警报(hasprototypeproperty(甲,名字)); / /假
使用在 / /回报都是通过对象访问,可枚举的属性,其中既包含原型属性包含一个实例的属性。
/ /盾牌原型(不可枚举属性标记为错误的可枚举属性)的实例属性将返回在
在早期版本的 / / IE有一个bug:在不可枚举属性实例属性盾牌原型不返回在
:
var
说明:函数(){
返回我的对象;
}
};
对于(var中的var){
如果(道具= =toString){
警报();在IE的早期版本中不显示
}
}
所有 / /可枚举属性来获取对象,您可以使用ecmascript5(对象。键)方法接受一个对象作为参数,
/ /包含所有可枚举属性的字符串数组
功能人(){
}
人。原型。名称=琥珀;
原型,年龄= 23;
人。原型。作业=软件工程师;
人的原型。sayname =函数(){
警报(这个名字)
}
VaR甲=新的人();
var 2 =新的人();
VAR键= object.keys(人。原型);
警报(钥匙)
甲。名称=琥珀。许;
把年龄= 23;
VAR键= object.keys(甲);
警报(钥匙)
警报(----------------------------------------- )
如果希望获得所有实例属性,而不管他是否可以枚举,可以使用。
警报(Object.getOwnPropertyNames(甲));
警报(object.getownpropertynames(人。原型));
警报(简单原型语法----------------------------------------- )
3,更简单的原型语法
功能人(){
}
人。原型= {
姓名:琥珀
年龄:23岁,
工作:软件
sayname:函数(){
警报(这个名字)
}
}
此属性不再在构造函数后写入,而是写入对象构造函数。
在 / /尽管返回正确的结果通过instanceof运算符可以,但构造函数已经无法确定对象的类型,如:
朋友=新人();
警报(朋友是人) / /真的
警报(朋友是对象) / /真的
警报(朋友,构造函数=人);
警报(朋友,构造函数=对象);
如果构造函数对您非常重要,那么将下列设置设置为适当的值
功能人(){
}
人。原型= {
构造函数:人,
姓名:琥珀
年龄:23岁,
工作:软件
SayName:function () {
警报(这个名字)
}
}
朋友=新人();
警报(手动设置构造函数----------------------------------------- )
警报(朋友,构造函数=人);
本手册 / /添加构造函数将成为构造函数可枚举元素(构造函数属性时,原不可数)。
在这种情况下,您可以使用
object.defineproperty(person.prototype,建设者
枚举:假,
人的价值:
});
动态原型
朋友=新人();
的人。原型。打个招呼=函数(){
警报(嗨);
}
Friend.sayHi(); / /嗨(正常运行)
由于实例和原型之间的关系是实例和原型之间松散的连接,所以连接只是一个指针而不是一个副本。
/ /当我们调用sayhi()方法,第一种方法叫sayhi搜索将在搜索的情况下,在没有找到原型。
但是如果要重写整个原型对象,那么情况就不一样了。
我们知道,调用构造函数将一个链接添加到原型原型指针中作为一个例子,原型被修改为另一个对象是在构造函数和初始原型之间进行切断的联系。
请记住:在指向原型的唯一点中,指针不在构造函数中,Eg:
函数(a){
var =新的a();
a.prototype = {
构造函数:a,
姓名:琥珀
年龄:23岁,
工作:软件
sayname:函数(){
警报(这个名字)
}
}
警报(错误------------------------------------- );
警报(a1.sayname());
/ /我们创建一个实例,然后将原型对象,然后调用a1.sayname()错误发生,因为属性命名的方法不包含一个指向原型
/本机对象原型
原型不仅反映了创建自定义类型的重要性,甚至所有本机引用类型都是在这个模式中创建的。
在其构造函数原型中定义的方法:
警报(typeof阵列。原型。排序); / /功能
警报(类型的字符串。原型。串); / /功能
不仅可以在本机对象原型中引用默认方法,而且可以定义新方法。
添加一个从 /字符串类型(法)
字符串。原型。从=功能(文本){
返回this.indexof(文本)= 0;
};
var;
警报(msg.startswith(H));
我们不建议做。
警报(原型对象的问题);
6和原型对象问题的一个示例
函数问题(){
}
Ques.prototype={
构造函数:问题,
姓名:琥珀
年龄:23岁,
工作:
好友:{ 三
sayname:函数(){
警报(这个名字)
}
};
VaR Q1 =新的问题();
VaR Q2 =新的问题();
q1.friends.push(王五);
警报(第一节,朋友);
警报(第二节好友);
警报(第一节,朋友,朋友);
我相信我们已经看到了这个问题,当我创建Q1和Q2的两个实例时,当我是Q1的朋友加上五之后,Q2的朋友有三个张三,Li Si,Wang Wu。
那是因为ques.prototype存在阵列/,而不是Q1。因此作为结果。
这就是这个问题,我们很少看到人们为什么使用单独的模式。
本文先在这里,然后我们将继续讨论Javascript面向对象编程,希望大家会喜欢它。