Javascript面向对象
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript面向对象相关的知识,希望对你有一定的参考价值。
在简书上看到了关于javascript面向对象的一些文章,突然也想写一点自己的见解。
按人们认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世界分析、设计、实现软件的办法
为什么要面相对象?
首先要了解什么是面向对象,面向对象有哪些特性。我在网上查到关于面相对象现在还没有统一的概念,如果没有统一的概念,我就先随便找个差不多的概念吧。如上,简单的说就是一切都是对象,什么是对象,对象就是对现实世界的抽象。
面相对象有什么特性,我在百度百科上找到几个,然后展开来说。
- 对象唯一性:对象是对现实世界的抽象,现实世界每样东西都是唯一的,所以对象也是唯一的。
- 抽象性:对象是对现实世界的抽象,比如说我们抽象人的概念,每个人都有姓名,性别,年龄等等,但是每个人又有不通的性格,然后我们把他抽象了出来,这就是抽象性
- 继承性:还是人的概念,我们抽象的东西为了实现能够多次的复用,我们一类具有相同属性的东西抽离出来,用于继承这样就能实现代码最大程度上的精简,并且富有逻辑,人类社会不就是这样的么,小明和小红的孩子身上会有小红和小明身上的一些特质,当然,他们的孩子身上也会有,一些小红和小明身上没有的特质。正式因为有这个特性,社会才会进步。
- 多态性:还是用人来举例子,每个人都有不同的名字,我叫每个人,每个人都会回答给我不一样的名字,但是我用了同样的方法去提问,这就是多态性,相同的方法,在不通的对象上体现出来的结果也是不同的。
Javascript如何实现面向对象,要讲Javascript面向对象之前首先要讲一下下面这些神奇的东西。
- this:对于Javascript来说,一切都是function,那么this的作用域就只是在function里面。这个其实很好理解,但是如果不实际操作那就不一定了,用代码说话。
var name = "ben";//ben 作用域是this.Window function persion() { alert(this.name); //benalert(name); //benthis.name = "jill";//ben function showAge() { var age = 25; alert(this.name);//jill alert(this.age);//undifine 作用域是 // **this.window,age 的作用域在showAge这个方法中** } showAge(); } alert(name);//ben alert(this.name);//ben persion();
prototype:这个东西太他妈重要了,要是不知道的话,别逼我骂人。
//首先说明原型 //这里先借用一个例子 //来自 //http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html function DOG(name){ this.name = name; this.species = ‘犬科‘; } var dogA = new DOG(‘大毛‘); var dogB = new DOG(‘二毛‘); dogA.species = ‘猫科‘; alert(dogB.species); //示犬科",不受dogA的影响 //下面是原型 function DOG(name){ this.name = name; } DOG.prototype = { species : ‘犬科‘ }; var dogB = new DOG(‘二毛‘); alert(dogA.species); // 犬科 alert(dogpecies); // 犬科 //下面是借用原型的实现 function Persion(name,age){ this.myName = name; this.myAge = age; } persion.prototype = { showName:function(){ alert(this.myName); }, showAge:function(){ alert(this.myAge); } } //这样一个人就抽象好了 var jack = new Persion("jack",25); var shell = new Persion("shell",25); jack.showName(); //jack shell.showName();//shell
constructor
//其实就是一只构造函数 function Persion(name,age){ this.myName = name; this.myAge = age; } Persion.prototype.showName = function(){ alert(this.myName); }; alert(Persion.constructor); var jack = new Persion("jack",25); alert(jack.constructor); //但是constructor是会被覆盖的 function Persion2(name,age){ this.myName = name; this.myAge = age; } Persion2.prototype ={ showName:function(){ alert(this.myName) } } alert(Persion2.constructor); var rose = new Persion("rose",25); alert(rose.constructor); //所以如果要用,并不安全,但是我们也要把他给考虑进去 //毕竟面向对象的都有构造函数 //咱不能掉队
call/apply
//这个玩意儿相当的重要,重要到无法代替。 //例子还是要举起来 function Persion(name,age){ this.name = name; this.age = age; } function Student(name,age,school){ Persion.call(this,name,age,school) this.school = school; } Student.prototype = { showName:function(){ alert(this.name); }, showSchool:function(){ alert(this.school); } } var jack = new Student("Jack","24","Jialidun"); jack.showName(); // Jack jack.showSchool();//Jialidun
arguments
//这个玩意给我们提供了太多的方便,难以言喻。 function Persion(name,age){ this.name = name; this.age = age; } Persion.prototype = { setSkills:function(){ for(var item in arguments){ alert(arguments[item]); } } } var jack = new Persion("Jack","24"); jack.setSkills("java","javascript","css","Node.js"); //这个例子充分表明了这个家伙是干什么用的。
基本概念讲完了,下面讲几个我见到过在项目里面做继承的几个示范:
第一个示范
/** * 实现继承类 * @private _object * */ function _object (o) { function F() { }; F.prototype = o; return new F(); } /** * * 实现继承 * @method inherit * @private * @param {Object} subType 子类 * @param {Object} superType 超类 * */ function inherit (subType, superType) { var p = _object(superType.prototype); p.constructor = subType; subType.prototype = p; } function Persion(name,age){ this.name = name; this.age = age; } Persion.prototype = { showName:function(){ alert(this.name); }, showAge:function(){ alert(this.age); } } function Student(name,age,school){ Persion.call(this,name,age); this.school = school; } inherit(Student,Persion); Student.prototype.showSchool = function(){ alert(this.school); } var jack = new Student("Jack",25,"jialidun"); jack.showName(); jack.showSchool();
第二个示范
function Persion(name,age){ this.name = name; this.age = age; } Persion.prototype = { showName:function(){ alert(this.name); }, showAge:function(){ alert(this.age); } } function Student(name,age,school){ Persion.call(this,name,age); this.school = school; } Student.prototype = new Persion(); //这块累赘了 //你知道如果这块不这样,像下面那样 //Student.prototype 和 Persion.prototype 就将是绑定死的 //意思就是如果你改变Student.prototype中的东西 //Persion.prototype也会变,很危险 //孩子怎么能影响父亲呢,大逆不道不是 //Student.prototype = Persion.prototype Student.prototype.showSchool = function(){ alert(this.school); } var jack = new Student("Jack",25,"jialidun"); jack.showName(); jack.showSchool();
第三个示范这个例子来自 Leaflet
/* * L.Class powers the OOP facilities of the library. * Thanks to John Resig and Dean Edwards for inspiration! */ L = {}; L.Util ={ extend: function (dest) { var i, j, len, src; for (j = 1, len = arguments.length; j < len; j++) { src = arguments[j]; for (i in src) { dest[i] = src[i]; } } return dest; }, // create an object from a given prototype create: Object.create || (function () { function F() {} return function (proto) { F.prototype = proto; return new F(); }; })()} L.Class = function () {}; L.Class.extend = function (props) { // extended class with the new prototype var NewClass = function () { // call the constructor if (this.initialize) { this.initialize.apply(this, arguments); } // call all constructor hooks this.callInitHooks(); }; var parentProto = NewClass.__super__ = this.prototype; var proto = L.Util.create(parentProto); proto.constructor = NewClass; NewClass.prototype = proto; // inherit parent‘s statics for (var i in this) { if (this.hasOwnProperty(i) && i !== ‘prototype‘) { NewClass[i] = this[i]; } } // mix static properties into the class if (props.statics) { L.Util.extend(NewClass, props.statics); delete props.statics; } // mix includes into the prototype if (props.includes) { L.Util.extend.apply(null, [proto].concat(props.includes)); delete props.includes; } // merge options if (proto.options) { props.options = L.Util.extend(L.Util.create(proto.options), props.options); } // mix given properties into the prototype L.Util.extend(proto, props); proto._initHooks = []; // add method for calling all hooks proto.callInitHooks = function () { if (this._initHooksCalled) { return; } if (parentProto.callInitHooks) { parentProto.callInitHooks.call(this); } this._initHooksCalled = true; for (var i = 0, len = proto._initHooks.length; i < len; i++) { proto._initHooks[i].call(this); } }; return NewClass; }; // method for adding properties to prototype L.Class.include = function (props) { L.Util.extend(this.prototype, props); }; // merge new default options to the Class L.Class.mergeOptions = function (options) { L.Util.extend(this.prototype.options, options); }; // add a constructor hook L.Class.addInitHook = function (fn) { // (Function) || (String, args...) var args = Array.prototype.slice.call(arguments, 1); var init = typeof fn === ‘function‘ ? fn : function () { this[fn].apply(this, args); }; this.prototype._initHooks = this.prototype._initHooks || []; this.prototype._initHooks.push(init); }; //现在开始使用了 Persion = L.Class.extend({ options:{ name:"", sex:"", age:"" }, initialize:function(options){ this.name = options.name; this.sex = options.sex; this.age = options.age; }, showName:function(){ alert(this.name); } }); Student = Persion.extend({ options:{ name:"", sex:"", age:"", school:"", score:"" }, initialize:function(options){ Persion.prototype.initialize.call(this, options); this.school = options.school; this.score = options.score; }, showSchool:function(){ alert(this.school); } }) var jack = new Student({ name:"jack", sex:"man", age:"25", school:"Beijing University", score:"A++" }); jack.showSchool();
这个继承有点长,但是很用,很有启发。简单写了一下用法,但是不全。
name:Jack
QQ:84201088