每天Javascript学习总结(面向对象编程)

1。面向对象工厂方法




功能createperson(姓名、年龄、工作){
新对象();
o.name =名称;
o.age =年龄;
o.job =工作;
o.sayname =函数(){
警报(这个名字);
};
回来啊;
}

甲= createperson VaR(尼古拉斯
var 2 = createperson(格雷戈

(甲。sayname); / /尼古拉斯
(2。sayname); / /格雷戈


工厂模型方法的缺点是产生大量重复的代码!

2。构造函数模式创建对象




功能人(姓名,年龄,工作){
this.name =名称;
this.age =年龄;
this.job =工作;
this.sayname =函数(){
警报(这个名字);
};
}

VaR甲=新的人(尼古拉斯
var 2 =新的人(格雷戈

(甲。sayname); / /尼古拉斯
(2。sayname); / /格雷戈

警报(甲实例对象); / /真的
警报(甲是人); / /真的
警报(2实例对象); / /真的
警报(2是人); / /真的

警报(person1.constructor = =人); / /真的
警报(person2.constructor = =人); / /真的

警报(person1.sayname = = 2。sayname); / /假


使用新关键字创建对象将经历以下四个过程

1。创建一个新对象
2。将构造函数的范围分配给一个新对象(因此指向新对象)
三.执行构造函数的方法(这个新对象的赋值)
4。返回一个新对象


三.使用构造函数作为函数


功能人(姓名,年龄,工作){
this.name =名称;
this.age =年龄;
this.job =工作;
this.sayname =函数(){
警报(这个名字);
};
}

var =新的人(尼古拉斯
(人。sayname); / /尼古拉斯

人(格雷戈
(窗口。sayname); / /格雷戈

新对象();
person.call(O,克里斯汀
(o.sayname); / /克里斯汀



构造函数作为一个函数使用,与普通函数没有任何区别;它是在窗口对象下添加的一种方法,因为构造函数创建的对象实际上是创建一个新对象,所以本质上,它们是不同的或分离的。他们的方法不同。

4。解决全局不一致性常用方法和方法的问题




功能人(姓名,年龄,工作){
this.name =名称;
this.age =年龄;
this.job =工作;
this.sayname = sayname;
}

功能sayname(){
警报(这个名字);
}

VaR甲=新的人(尼古拉斯
var 2 =新的人(格雷戈

(甲。sayname); / /尼古拉斯
(2。sayname); / /格雷戈

警报(甲实例对象); / /真的
警报(甲是人); / /真的
警报(2实例对象); / /真的
警报(2是人); / /真的

警报(person1.constructor = =人); / /真的
警报(person2.constructor = =人); / /真的

警报(person1.sayname = = 2。sayname); / /真的


虽然上面的方法解决了同样的问题,但是定义的全局方法属于窗口本身,所以局部和全局不分离!所以这个方法没有多大用途!这是不推荐的。

5,原型模型

我们创建的任何函数都有一个原型对象。这个属性是一个指针,它指向一个对象,这个对象的操作是一个可以共享特定类型的所有实例的方法。




功能人(){
}

person.prototype.name = 尼古拉斯;
person.prototype.age = 29;
person.prototype.job =软件工程师;
person.prototype.sayname =函数(){
警报(这个名字);
};

VaR甲=新的人();
(甲。sayname); / /尼古拉斯

2 var =人新();
(2。sayname); / /尼古拉斯

警报(person1.sayname = = 2。sayname); / /真的

警报(person.prototype.isprototypeof(甲)); / /真的
警报(person.prototype.isprototypeof(2)); / /真的

/ /只有当Object.getPrototypeOf()是可用的
如果(物体。getprototypeof){
警报(Object.getPrototypeOf(甲)=人。原型); / /真的
警报(Object.getPrototypeOf(甲)。名称); / /尼古拉斯
}



理解原型

每当创建一个函数时,就会创建一个原型属性,它指向函数的原型对象,默认情况下,原型对象包含一个构造函数(构造函数属性),它包含一个指向原型属性函数的指针。

属性阅读顺序

每当一个对象代码读取属性时,就会执行一个搜索,目标属性用给定的名称,从对象实例本身开始搜索,如没有返回,将继续搜索对象的原型链,直到搜索到原型链的外层!




功能人(){
}

person.prototype.name = 尼古拉斯;
person.prototype.age = 29;
person.prototype.job =软件工程师;
person.prototype.sayname =函数(){
警报(这个名字);
};

VaR甲=新的人();
2 var =人新();

person1.name = 格雷戈;
警报(甲的名字); / / 格雷戈的例子
警报(2名); / / 尼古拉斯的原型



如果删除此元素的实例属性




功能人(){
}

person.prototype.name = 尼古拉斯;
person.prototype.age = 29;
person.prototype.job =软件工程师;
person.prototype.sayname =函数(){
警报(这个名字);
};

VaR甲=新的人();
2 var =人新();

person1.name = 格雷戈;
警报(甲的名字); / /格雷戈从实例
警报(2名); / /尼古拉斯从原型

删除person1.name;
警报(甲的名字); / / 尼古拉斯的原型



6、hasownproperty方法

此方法可以检测实例中或原型中是否存在属性!hasownproperty继承对象并将返回真。只要给定的属性存在于对象实例中




功能人(){
}

person.prototype.name = 尼古拉斯;
person.prototype.age = 29;
person.prototype.job =软件工程师;
person.prototype.sayname =函数(){
警报(这个名字);
};

VaR甲=新的人();
var 2 =新的人();

警报(person1.hasownproperty(名称)); / /假
警报(名在甲); / /真的

person1.name = 格雷戈;
警报(甲的名字); / /格雷戈从实例
警报(person1.hasownproperty(名称)); / /真的
警报(名在甲); / /真的

警报(2名); / /尼古拉斯从原型
警报(person2.hasownproperty(名称)); / /假
警报(名在2); / /真的

删除person1.name;
警报(甲的名字); / / 尼古拉斯的原型
警报(person1.hasownproperty(名称)); / /假
警报(名在甲); / /真的



7,Object.keys()可枚举属性的方法

这个方法接受一个对象作为参数,并返回包含所有可枚举属性的字符串数组




功能人(){
}

person.prototype.name = 尼古拉斯;
person.prototype.age = 29;
person.prototype.job =软件工程师;
person.prototype.sayname =函数(){
警报(这个名字);
};

VAR键= object.keys(人。原型);
警报(键); / /姓名,年龄,职业,sayname
如果您想获得实例的所有属性,可以使用该方法获得它是否可以枚举。
功能人(){
}

person.prototype.name = 尼古拉斯;
person.prototype.age = 29;
person.prototype.job =软件工程师;
person.prototype.sayname =函数(){
警报(这个名字);
};

VAR键= object.getownpropertynames(人。原型);
警报(键); / /构造函数,姓名,年龄,职业,sayname



此方法由浏览器的高级版本支持。

8,简单原型法




功能人(){
}

person.prototype = { {
姓名:尼古拉斯
年龄:29岁,
工作:软件工程师
sayname:函数(){
警报(这个名字);
}
};

朋友=新人();

警报(朋友是对象); / /真的
警报(朋友是人); / /真的
警报(friend.constructor = =人); / /假
警报(friend.constructor = =对象); / /真的




重写原型等于缺省原型法,然后重写相同的构造方法,重写的构造方法指向对象对象!而不是原来的对象

如果您想指向前面的构建方法,可以展示它




功能人(){
}

person.prototype = { {
构造函数:人,
姓名:尼古拉斯
年龄:29岁,
工作:软件工程师
sayname:函数(){
警报(这个名字);
}
};

朋友=新人();

警报(朋友是对象); / /真的
警报(朋友是人); / /真的
警报(friend.constructor = =人); / /真的
警报(friend.constructor = =对象); / /假




9,动态加法的原型法




功能人(){
}

person.prototype = { {
构造函数:人,
姓名:尼古拉斯
年龄:29岁,
工作:软件工程师
sayname:函数(){
警报(这个名字);
}
};

朋友=新人();

person.prototype.sayhi =函数(){
警报(嗨);
};

friend.sayhi(你好); / /作品!



10。本地对象的原型




警报(typeof阵列。原型。排序); / / 功能
警报(类型的字符串。原型。串); / / 功能

string.prototype.startswith =功能(文本)原型法{ / /修改本地对象
返回this.indexof(文本)= 0;
};

Hello World!;
警报(msg.startswith(你好)); / /真的




11。将构造函数和原型模式组合起来创建对象




构造函数模式
功能人(姓名,年龄,工作){
this.name =名称;
this.age =年龄;
this.job =工作;
this.friends = {谢尔比
}
原型
person.prototype = { {
构造函数:人,
sayname:函数(){
警报(这个名字);
}
};

VaR甲=新的人(尼古拉斯
var 2 =新的人(格雷戈

person1.friends.push(车);

警报(甲。朋友); / /谢尔比,法庭上,范
警报(2。朋友); / /谢尔比,法院
警报(person1.friends = 2。朋友); / /假
警报(person1.sayname = 2。sayname); / /真的



12。动态原型模式




功能人(姓名,年龄,工作){

属性
this.name =名称;
this.age =年龄;
this.job =工作;

方法
如果(typeof this.sayname!=函数{){

person.prototype.sayname =函数(){
警报(这个名字);
};

}
}

var =新朋友(尼古拉斯)
Friend.sayName();




13,寄生构造函数模式




功能人(姓名,年龄,工作){
var =新的(对象);依赖全局对象初始化一个对象,然后返回对象。
o.name =名称;
o.age =年龄;
o.job =工作;
o.sayname =函数(){
警报(这个名字);
};
回来啊;
}

var =新朋友(尼古拉斯)
(朋友sayname); / /尼古拉斯

函数的SpecialArray(){

创建数组
var =新数组();

添加值
values.push.apply(值、参数);

分配方法
values.topipedstring =函数(){
返回this.join(| );
};

返回
返回值;
}

VaR的颜色=新specialarray(红
警报((颜色。topipedstring)); / /红蓝绿| |

警报(颜色是specialarray);




上诉的方式有点清楚。因为它依赖于外部对象来创建新的对象,它不能依赖instanceof方法确定属性和方法的来源。它实际上是不相关的构造函数!

14,稳定的构造函数模型




功能人(姓名,年龄,工作){
新对象();
o.sayname =函数(){
警报(名称);
};
回来啊;
}

var =尼古拉斯()
(朋友sayname); / /尼古拉斯



此方法不依赖于任何新的密钥!如果您想访问对象的方法和属性,只能通过定义对象的方式获得它。

15。继承

Javascript实现是通过原型链实现的。




函数的SuperType(){
this.property = true; / /定义属性
}

supertype.prototype.getsupervalue =函数()方法{ / /原型定义
返回this.property;
};

函数SubType(){
this.subproperty = false;
}

/ /继承父类型
subtype.prototype =新类型();

subtype.prototype.getsubvalue =函数(){
返回this.subproperty;
};

var实例=新的子类型();
警报(instance.getsupervalue()); / /真的

警报(实例实例对象); / /真的
警报(实例实例类型); / /真的
警报(实例是亚型); / /真的

警报(Object.prototype.isPrototypeOf(实例)); / /真的
警报(supertype.prototype.isprototypeof(实例)); / /真的
警报(subtype.prototype.isprototypeof(实例)); / /真的
类型继承的属性和方法的类型,所以当实例可以直接调用父类的方法!
函数的SuperType(){
this.property =真;
}

supertype.prototype.getsupervalue =函数(){
返回this.property;
};

函数SubType(){
this.subproperty = false;
}

/ /继承父类型
subtype.prototype =新类型();

/新方法
subtype.prototype.getsubvalue =函数(){
返回this.subproperty;
};

覆盖现有方法
subtype.prototype.getsupervalue =函数(){
返回false;
};

var实例=新的子类型();
警报(instance.getsupervalue()); / /假




上面的例子表明重写后的原型将覆盖以前的继承原型,最终的回报往往不是预期的效果。




函数的SuperType(){
this.property =真;
}

supertype.prototype.getsupervalue =函数(){
返回this.property;
};

函数SubType(){
this.subproperty = false;
}

/ /继承父类型
subtype.prototype =新类型();

对上述失败的方法使用文字添加的方法
subtype.prototype = { {
GetSubValue:函数(){
返回this.subproperty;
},

someothermethod:函数(){
返回false;
}
};

var实例=新的子类型();
console.log(实例);
警报(instance.getsupervalue()); / /错误!



下面的示例也显示重写原型的风险




函数的SuperType(){
this.colors = {红
}

函数SubType(){
}

/ /继承父类型
subtype.prototype =新类型();

请为新的亚型(VAR);
instance1.colors.push(黑);
(请警惕。颜色); / /红色,蓝色,绿色,黑色的

无功instance2 =新的亚型();
警报(instance2。颜色); / /红色,蓝色,绿色,黑色的




原型共享产生两个不同对象调用的相同数据。

16。使用构造函数进行继承




函数的SuperType(){
this.colors = {红
}

函数SubType(){
/ /继承父类型
supertype.call(本);
}

请为新的亚型(VAR);
instance1.colors.push(黑);
(请警惕。颜色); / /红色,蓝色,绿色,黑色的

无功instance2 =新的亚型();
警报(instance2。颜色); / /红、蓝、绿




传递参数




函数的SuperType(化名){
this.name =名称;
}

函数SubType(){
/ /继承父类型传递参数
(这supertype.call,尼古拉斯);

实例属性
this.age = 29;
}

var实例=新的子类型();
警报(实例名称);尼古拉斯;
警报(实例.年龄);29




17,组合继承




函数的SuperType(化名){
this.name =名称;
this.colors = {红
}

supertype.prototype.sayname =函数(){
警报(这个名字);
};

函数SubType(名称,年龄){
supertype.call(这名字);

this.age =年龄;
}




18,原型继承




函数对象(o){
函数(f){ }
f.prototype = O;
返回新的f();
}

var
姓名:尼古拉斯
好友:{谢尔比
};

无功的人=对象(人);
anotherperson.name = 格雷戈;
AnotherPerson.friends.push(抢);



19,寄生组合遗传




函数对象(o){
函数(f){ }
f.prototype = O;
返回新的f();
}

功能inheritprototype(亚型,超型){
VaR的原型=对象(父类型。原型); / /创建对象
prototype.constructor =亚型; / /增加对象
subtype.prototype =原型; / /分配对象
}

函数的SuperType(化名){
this.name =名称;
this.colors = {红
}

supertype.prototype.sayname =函数(){
警报(这个名字);
};

函数SubType(名称,年龄){
supertype.call(这名字);

this.age =年龄;
}

InheritPrototype(亚型,超型);

subtype.prototype.sayage =函数(){
警戒(这个年龄);
};

VaR请=新的亚型(尼古拉斯
instance1.colors.push(黑);
(请警惕。颜色); / /红色,蓝色,绿色,黑色的
(请。sayname); / /尼古拉斯;
instance1.sayage(); / / 29


无功instance2 =新的亚型(格雷戈
警报(instance2。颜色); / /红、蓝、绿
(instance2。sayname); / /格雷戈;
instance2.sayage(); / / 27



以上就是今天的javascript学习总结,然后每天都会继续更新,希望大家继续关注。