js面向对象总结
2011-08-21 20:54
507 查看
出处http://www.cnblogs.com/ilexcai/archive/2011/08/19/2145596.html
一、首先创建js对象的四种方式:
1.普通模式
但是这样每次去创建一个类的对象相当的麻烦。所以有了下面的集中创建对象的模式。
2.工厂模式
这样就创建一一个person类(并不是真正意义上的方法,其实我们能看到,它只不过是一个方法,一个Object的对象的实例而已,里面所谓的属性,只不过是以Object特有的键值对的形式存在)。
这个结果,应该猜都能猜出来。
3.构造函数模式
new关键字:
开辟堆空间;
创建对象;
将构造函数作用域赋值给新对象(this就指向了该新对象);
执行构造函数中的代码(为新对象添加属性);
返回新对象
4.原型模式,其实上面的集中方法都有大家看不到的缺陷。
每个实例上都有自定义的各个方法对象,这样多个对象调用这个方法的时候就消耗内存资源。我们在想能不能让同一个类的对象都区调用同一个方法对象。这样就不会占用那么多的内存空间。
好,这个时候prototype的好处就体现了。
二、继承
1.方法的继承,首先用原型模式创建一个父类。
2.创建子类,
如何判断stu继承了person?只要stu能点出sayHi这个方法出来就证明stu能够调用这个方法,也就是说继承了这个方法。
stu.sayHi();很显然的能点出来,运行的话,会弹出undefinde,既然弹出了,就证明方法执行了,方法执行了就证明方法继承过来的,至于弹出的我们下面来解决。//这样子类student就能够继承父类的方法。
但是这样父类的属性还没有继承过来,这个时候就需要考虑用到apply或者call方法,来改变函数的作用域了。
我们更改下这个子类的构造函数
这个时候我们在执行sayhi这个方法的时候就会弹出panpan。那这个时候我们的继承就好解决了,我们可以在student这个类中传2个参数,name,age。然后在apply中的第二个参数设置为name和age的数组。
好吧,我们看下完整的代码。
这样我们的继承问题就解决了。
这个代码是把person的原型指针赋给了student的原型,也就是说我们给Student.prototype添加一个属性的时候,父类person也会具有这个属性。
这个时候就会弹出“明明我在吃饭”
但是
这个代码必须放在
之后,因为代码是从上到下执行的。
在没有给原型指针添加属性方法的时候是没办法访问到的。
上述的代码也就是说我们在给子类添加方法的时候,我们父类也有了这些方法,但是理论上来说对于继承是不允许这样的。
那么我们怎么对子类添加方法而不会使父类也拥有这些方法呢。
我们看一下,stu调用sayHi方法是怎么执行的。
首先创建一个stu的对象,在栈上保存这个变量stu,在堆上保存new出来的对象,stu这个变量指向堆上对象的地址。当我们调用stu的sayHi方法时,首先会到student这个对象去找方法,找不到这个方法,然后去原型里面去找, 由于这个方法的原型实质上是person类的原型的地址。所有就到person类中区找,找到了就调用这个方法。
如果我们将子类的原型指向父类的对象呢?
这就是所谓的原型继承。
这里我补充下继承的几种方法,上面的内容涉及到原型继承和类继承(构造函数继承),一般的类继承会使用call\apply函数去尝试绑定一个访问关系,让子类能够访问的父类的实例属性。这里就不多说,下面介绍一种实例继承,一般是用来封装系统对象的,也可以引用到自定义对象。如下:
js面向对象总结
关于js面向对象的内容很多,很多人看书觉得很乱。因为内容太多了,又是原型,又是继承什么的。今天在园里看到“农村出来的大学生”写得一些js面向对象总结,自己一扫而过,很清晰,现在分享出来。一、首先创建js对象的四种方式:
1.普通模式
1 var person=new Object(); 2 person.name="盼盼"; 3 person.age=22; 4 person.sayHi=function(){ 5 alert(this.name); 6 }
但是这样每次去创建一个类的对象相当的麻烦。所以有了下面的集中创建对象的模式。
2.工厂模式
1 function person(name,age){ 2 var p=new Object(); 3 p.name=name; 4 p.age=age; 5 p.sayHi=function(){ 6 alert(this.name); 7 }; 8 return p; 9 }
这样就创建一一个person类(并不是真正意义上的方法,其实我们能看到,它只不过是一个方法,一个Object的对象的实例而已,里面所谓的属性,只不过是以Object特有的键值对的形式存在)。
1 var p1 = person("盼盼",22); 2 var p2 = person("明明",26); 3 p1.sayHi(); 4 p2.sayHi();
这个结果,应该猜都能猜出来。
3.构造函数模式
1 function person(name,age){ 2 this.name=name; 3 this.age=age; 4 this.sayHi=function(){ 5 alert(this.name);}; 6 } 7 var p1 = new person("盼盼",22); 8 var p2 = new person("明明",26); 9 p1.sayHi(); 10 p2.sayHi();
new关键字:
开辟堆空间;
创建对象;
将构造函数作用域赋值给新对象(this就指向了该新对象);
执行构造函数中的代码(为新对象添加属性);
返回新对象
4.原型模式,其实上面的集中方法都有大家看不到的缺陷。
每个实例上都有自定义的各个方法对象,这样多个对象调用这个方法的时候就消耗内存资源。我们在想能不能让同一个类的对象都区调用同一个方法对象。这样就不会占用那么多的内存空间。
好,这个时候prototype的好处就体现了。
1 function person(name,age){ 2 this.name=name; 3 this.age=age; 4 } 5 person.prototype.sayHi=function(){ 6 alert(this,name); 7 } 8 var p1 = new person("盼盼",22); 9 var p2 = new person("明明",26); 10 p1.sayHi(); 11 p2.sayHi();
二、继承
1.方法的继承,首先用原型模式创建一个父类。
1 function Person(name,age){ 2 this.name=name; 3 this.age=age; 4 } 5 Person.prototype.sayHi=function(){ 6 alert(this,name); 7 }
2.创建子类,
1 function Student() 2 { 3 } 4 Student.prototype=Person.prototype; 5 var stu=new Person();
如何判断stu继承了person?只要stu能点出sayHi这个方法出来就证明stu能够调用这个方法,也就是说继承了这个方法。
stu.sayHi();很显然的能点出来,运行的话,会弹出undefinde,既然弹出了,就证明方法执行了,方法执行了就证明方法继承过来的,至于弹出的我们下面来解决。//这样子类student就能够继承父类的方法。
但是这样父类的属性还没有继承过来,这个时候就需要考虑用到apply或者call方法,来改变函数的作用域了。
我们更改下这个子类的构造函数
1 function Student() 2 { 3 Person.apply(this,["panpan",22]) 4 }
这个时候我们在执行sayhi这个方法的时候就会弹出panpan。那这个时候我们的继承就好解决了,我们可以在student这个类中传2个参数,name,age。然后在apply中的第二个参数设置为name和age的数组。
1 function Student(name, age) { 2 Person.apply(this, [name, age]) 3 }
好吧,我们看下完整的代码。
1 function Person(name, age) { 2 this.name = name; 3 this.age = age; 4 } 5 Person.prototype.sayHi = function () { 6 alert(this.name); 7 } 8 function Student(name, age) { 9 Person.apply(this, [name, age]) 10 } 11 Student.prototype = Person.prototype; 12 var stu = new Student("盼盼", "22"); 13 stu.sayHi();
这样我们的继承问题就解决了。
1 Student.prototype = Person.prototype;
这个代码是把person的原型指针赋给了student的原型,也就是说我们给Student.prototype添加一个属性的时候,父类person也会具有这个属性。
1 Student.prototype.eat = function () { 2 alert(this.name+"我在吃饭"); 3 } 4 var per = new Person("明明", 26); 5 per.eat();
这个时候就会弹出“明明我在吃饭”
但是
1 var per = new Person("明明", 26); 2 per.eat();
这个代码必须放在
1 Student.prototype.eat = function () { 2 alert(this.name+"我在吃饭"); 3 }
之后,因为代码是从上到下执行的。
在没有给原型指针添加属性方法的时候是没办法访问到的。
上述的代码也就是说我们在给子类添加方法的时候,我们父类也有了这些方法,但是理论上来说对于继承是不允许这样的。
那么我们怎么对子类添加方法而不会使父类也拥有这些方法呢。
我们看一下,stu调用sayHi方法是怎么执行的。
首先创建一个stu的对象,在栈上保存这个变量stu,在堆上保存new出来的对象,stu这个变量指向堆上对象的地址。当我们调用stu的sayHi方法时,首先会到student这个对象去找方法,找不到这个方法,然后去原型里面去找, 由于这个方法的原型实质上是person类的原型的地址。所有就到person类中区找,找到了就调用这个方法。
如果我们将子类的原型指向父类的对象呢?
1 Student.prototype = new Person();
这就是所谓的原型继承。
这里我补充下继承的几种方法,上面的内容涉及到原型继承和类继承(构造函数继承),一般的类继承会使用call\apply函数去尝试绑定一个访问关系,让子类能够访问的父类的实例属性。这里就不多说,下面介绍一种实例继承,一般是用来封装系统对象的,也可以引用到自定义对象。如下:
1 function A(){ 2 this.x = 1; 3 } 4 function B(){ 5 var aObj = new A(); 6 aObj.getX = function(){ //定义访问入口 7 alert(aObj.x); 8 } 9 return aObj; 10 } 11 var bObj = new B(); 12 bObj.getX();
相关文章推荐
- js面向对象总结(一)
- js面向对象工作总结
- js面向对象学习总结
- JS面向对象总结
- js面向对象总结
- js的面向对象总结
- js总结(三):面向对象,prototype ,oo模拟
- js面向对象总结
- JS面向对象(智能社面向对象知识点总结)
- JS 面向对象实现 学习总结
- JS面向对象(智能社面向对象知识点总结)
- Java面向对象总结(高级篇)
- 浅谈JS的面向对象
- 软件工程总结——传统软件开发方法与面向对象开发方法的比较
- java面向对象笔记总结
- js对象深复制的方法总结(包装对象,Date对象,正则对象)
- 第163天:js面向对象-对象创建方式总结
- js面向对象理解。
- js面向对象原型属性和实例属性
- 黑马程序员《java基础总结(三)》(面向对象特点--继承)