JavaScript 面向对象思想以及原型、继承
来源:互联网 发布:黑苹果mac os 11.12 编辑:程序博客网 时间:2024/06/01 09:52
首先,回顾一下JavaScript 对象的概念。每个对象中封装了一些属性和方法,并且这一部分保存在堆内存中,而每个对象实例其实是一个句柄,也就是一个指针,指向堆内存中的那块数据,所以说,这是JavaScript的引用类型。
我们创建对象有这么几种方法:
1. 对象字面值的方法:
var person = { name : 'liu', age : 22, sayHello : function(){ alert(this.name); }}此时创建的对象person拥有两个属性和一个方法。
2. 工厂模式:
function CreateObject(name, age){ var o = new Object(); o.name = name; o.age = age; o.sayHello = function(){ alert(this.name); }; return o;}
var person = CreateObject('liu', 22);这种创建对象的方法可以得到一个新对象,但却不能区分对象的类型,因为都是从Object()类型new出来的。为了使得我们自定义的对象能够有自己的类型,所以才有了构造函数这种方法。
3. 构造函数
function Person(name, age){ this.name = name; this.age = age; this.sayHello = function(){ alert(this.name); }}
var p = new Person('liu', 22);
var p1 = new Person('Yang', 25);利用这种方法创建对象,可以看到p 和p1两个对象都拥有同名方法sayHello,但其实两者是不同的,因为函数也是对象,其实
this.sayHello = function(){ alert(this.name); }等价于如下代码
this.sayHello = new Function("alert(this.name)");也就是说每创建一个对象,就会创建一个新的函数。所以这样就会使得很多相同的函数重复被创建。因此,有这样一种解决方法:
function Person(name, age){ this.name = name; this.age = age; this.sayHello = sayHello_new; }}
function sayHello_new(){alert(this.name);}这样,p和p1对象共享的是一份函数代码,解决了上面提到的问题。但这样又会存在另一个问题,就是说如果我们要共享的方法很多很多时,就需要把这些方法都在全局作用域中添加,这样一方面失去了封装的意义,一方面使得该方法并不是所有对象都特有的,在全局作用域中也能被调用。基于这样的问题,我们的原型得以应用。4. 原型那什么是原型呢?原型(prototype)是每个函数都有的属性,这个属性其实就是一个指针,指向一个对象,这个对象叫做函数的原型对象。该原型对象中又有一个constructor属性,指向该函数本身。我们用下图来表示可能更清晰一些。而Person的实例对象中,有一个内部的属性[[Prototype]]也指向Person的原型对象。在浏览器控制台中,可以看到,对象实例中有一个__proto__属性,这个属性就指向Person的原型对象。而此时原型对象也有__proto__属性,该属性又指向原型的原型,这里是Object了。如下图所示,这就构成了所谓的原型链,我们在访问某个对象的属性或方法时,先看对象实例中是否存在,若存在,直接返回;若不存在,就沿着原型链搜索,直到找到查找属性或者到达原型链的末端。继承:在其他OO语言中,存在两种继承,一种是接口继承,另一种是实现继承。(接口继承大概就是根据函数声明来继承,实现继承是包括函数实现的继承),而在JS中,由于不存在函数声明,也就是说没有函数定义,所以在JS中只有实现继承这一种方式。实现继承主要是利用原型链的概念:(看下面代码)function Person(name, age){ this.name = name; this.age = age;this.sayHello = function(){alert(this.name);}}function Stu(){this.job = 'student';}Stu.prototype = new Person('Liu', 22);var s = new Stu();s.sayHello(); //弹出 Liu的框var s1 = new Stu();s1.sayHello();此时,s和s1共享了Person中的属性和方法。再考虑这么一种情况,如果Person里面的属性有引用类型的值,比如this.friend = ['wan', 'Yang', 'Chen'];如果s.friend.push('Hellen') ;s1的friend属性也会发生变化。因为他们共享的是一个friend数组。为了解决这个问题,必须让这些引用属性保存在独自的实例对象中。有一种叫伪造对象的方法可以解决这种问题。function Person(name, age){ this.name = name;this.age = age;this.friend = ['Yang', 'Chen', 'wan'];}function Stu(name, age){Person.call(this, name, age);}Stu.prototype = {sayName : function(){alert(this.name);},job: 'student'}var stu1 = new Stu('Liu', 22);var stu2 = new Stu("Yang", 25);stu1.friend.push('Hellen'); //'Yang', 'Chen', 'wan','Hellen'stu2.friend.shift(); //'Chen', 'wan'这样,既可以保留自身实例对象的属性方法,也可以实现共享的属性和方法。后面这部分由于格式比较乱,所以另外整理了一篇博客,可以转到这里 后面这部分由于格式比较乱,所以另外整理了一篇博客,可以转到这里
阅读全文
0 0
- JavaScript 面向对象思想以及原型、继承
- JavaScript 面向对象思想以及原型、继承
- JavaScript 面向对象思想以及原型、继承
- JavaScript 面向对象与原型、继承
- javascript面向对象(原型、继承)
- 面向对象--原型继承
- Javascript的原型继承思想
- Javascript 面向对象原型
- JavaScript面向对象-原型
- JavaScript面向对象编程之prototype原型与继承
- JavaScript-形象理解面向对象、原型和继承
- 深入javascript面向对象,js的原型链、继承
- Javascript面向对象(三)——原型继承
- javascript面向对象思想
- javascript面向对象思想
- 什么是面向对象,原型,原型链继承
- 面向对象编程思想--继承
- js面向对象之继承-原型继承
- svn入门
- 今天做到一道面试题:Handler+Looper+MessageQueue+Message的关系
- ACM 第八届山东省赛 F quadratic equation SDUT 3898
- Cookie/Session机制详解
- android 触摸事件的处理与总结
- JavaScript 面向对象思想以及原型、继承
- 求pai的近似值
- oracle 游标细节引发的错误
- 勘探油田
- xtu-1269 Similar Subsequence(dp+树状数组)
- RCNN, Fast-RCNN, Faster-RCNN
- 深度学习常见的基本概念整理
- Java List集合使用方法介绍(1)
- 对树蛙培训的总结和体会