JavaScript定义类
来源:互联网 发布:mac版ae插件安装路径 编辑:程序博客网 时间:2024/06/01 09:29
参考了阮一峰老师的博客:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html
JavaScript语言部支持“类”,但是可以用一些变通的方法,模拟出“类”。
有三种方法:构造函数、Object.create()、极简主义(推荐)
一、构造函数的方式
构造函数其实就是普通的函数,只不过在内部用this关键字指代实例对象,生成实例的时候需要使用new关键字,并且可以在构造函数的prototype对象上定义实例的公共属性。
function Cat() { this.name = "大毛"; } var cat1 = new Cat(); alert(cat1.name); // 大毛 Cat.prototype.makeSound = function(){ alert("喵喵喵"); }
使用这种方法实现继承,一共有5中方法:1.构造函数绑定;2. prototype模式; 3. 直接继承prototype; 4. 利用空对象作为中介; 5. 拷贝继承
比如,现在有一个“动物”对象的构造函数
function Animal(){ this.species = "动物"; }
还有一个“猫”对象的构造函数
function Cat(name,color){ this.name = name; this.color = color; }
如何让“猫”继承“动物”呢?
1.构造函数绑定
使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象中加一行:
function Cat(name,color){ Animal.apply(this, arguments); this.name = name; this.color = color; } var cat1 = new Cat("大毛","黄色"); alert(cat1.species); // 动物
2. prototype模式
把猫的prototyhpe对象,指向一个Animal的实例,那么所有猫的实例,就能继承Animal了。但是,任何一个prototype对象都有一个constructor,指向它的构造函数,为了保证继承链不紊乱,必须使新的prototype对象的constructor属性指回原来的构造函数:
Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; var cat1 = new Cat("大毛","黄色"); alert(cat1.species); // 动物 Cat.prototype = new Animal(); Cat.prototype.constructor = Cat;
3. 直接继承 prototype
这种方法是对方法2的改进,由于Animal对象中,不变的属性都可以写入Animal.prototype。所以,可以让Cat直接继承Animal.prototype
function Animal(){ } Animal.prototype.species = "动物"; Cat.prototype = Animal.prototype; Cat.prototype.constructor = Cat; var cat1 = new Cat("大毛","黄色"); alert(cat1.species); // 动物
与方法2对比,这样做不用建立Animal实例,所以省内存,效率比较高,缺点是Cat.prototype和Animal.prototype指向了同一个对象,那么任何对于Cat.prototype的修改,都会反应到Animal.prototype。
所以上述代码中Cat.prototype.constructor = Cat;是有问题的,这一句把Animal.prototype的constructor属性也改了!
4. 利用空对象作为中介
针对方法3的缺点,可以利用一个空对象作为中介
var F = function(){}; F.prototype = Animal.prototype; Cat.prototype = new F(); Cat.prototype.constructor = Cat;
F是空对象,所以几乎不占内存,可以把上述方法封装成一个函数,便于使用:
function extend(Child, Parent) { var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; }
使用的时候方法如下:
extend(Cat,Animal); var cat1 = new Cat("大毛","黄色"); alert(cat1.species); // 动物
这个extend函数,就是YUI库如何实现继承的方法。
另外 Child.uber = Parent.prototype;意思是为字段想设置一个uber属性,uber是一个德语词,意思是“上一层”。等于在子对象上打开一条通道,可以直接调用父徐i想的方法。这一行只是为了实现继承的完备性,纯属备用性质。
5. 拷贝继承
把父对象的所有属性和方法,拷贝进子对象,也能实现继承
function Animal(){} Animal.prototype.species = "动物"; function extend2(Child, Parent) { var p = Parent.prototype; var c = Child.prototype; for (var i in p) { c[i] = p[i]; } c.uber = p; } extend2(Cat, Animal); var cat1 = new Cat("大毛","黄色"); alert(cat1.species); // 动物
二、 Object.create()
用这个方法,类是一个对象,而不是函数。这个方法不能实现私有属性和私有方法,实例对象之间也不能共享数据,对类的模拟不够全面。
var Cat = { name: "大毛", makeSound: function(){ alert("喵喵喵"); } }; var cat1 = Object.create(Cat); alert(cat1.name); // 大毛 cat1.makeSound(); // 喵喵喵
如果使用版本比较低的浏览器:
if (!Object.create) { Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; }
三、极简主义
它也是用一个对象模拟类,这个类里面,定义一个构造函数createNew(),用来生成实例。
var Cat = { createNew: function(){ // some code here } };
然后在createNew()里,顶一个实例对象,把这个对象作为返回值。
var Cat = { createNew: function(){ var cat = {}; cat.name = "大毛"; cat.makeSound = function(){ alert("喵喵喵"); }; return cat; } };
要让一个类继承另外一个类,只要在前者的createNew()中调用后者的createNew()方法即可。
var Animal = { createNew: function(){ var animal = {}; animal.sleep = function(){ alert("睡懒觉"); }; return animal; } }; var Cat = { createNew: function(){ var cat = Animal.createNew(); cat.name = "大毛"; cat.makeSound = function(){ alert("喵喵喵"); }; return cat; } }; var cat1 = Cat.createNew(); cat1.sleep(); // 睡懒觉
在createNew()方法中,只要不是定义在cat对象上的方法和属性,都是私有的。
var Cat = { createNew: function(){ var cat = {}; var sound = "喵喵喵"; cat.makeSound = function(){ alert(sound); }; return cat; } }; var cat1 = Cat.createNew(); alert(cat1.sound); // undefined
把需要共享的数据封装在类对象的里面、createNew()方法的外面即可。
var Cat = { sound : "喵喵喵", createNew: function(){ var cat = {}; cat.makeSound = function(){ alert(Cat.sound); }; cat.changeSound = function(x){ Cat.sound = x; }; return cat; } }; var cat1 = Cat.createNew(); var cat2 = Cat.createNew(); cat1.makeSound(); // 喵喵喵 cat2.changeSound("啦啦啦"); cat1.makeSound(); // 啦啦啦
- Javascript定义类:Javascript定义类
- javascript 类的定义
- javascript如何定义类
- JavaScript 定义类
- javascript定义类
- Javascript中定义类
- Javascript中定义类
- javascript定义类
- Javascript中定义类
- Javascript中定义类
- Javascript中定义类
- JavaScript类定义
- Javascript中定义类
- javascript定义类
- javascript定义类
- Javascript定义”类“
- Javascript中定义类
- javascript中定义类
- 再谈java内存模型
- MATLAB
- 开源堡垒机或者运维安全审计系统
- Canvas。。。。
- I am invited to be a mentor and translator in the mooc community
- JavaScript定义类
- startActivityForResult和setResult详解
- C# MATLAB混编(一)
- redis数据类型(一)字符串
- 自定义控件-自定义动画的下来刷新
- 二进制中有多少个1
- BZOJ3653——谈笑风生(dfs序 && 树状数组)
- SQL Server 2008 阻止保存要求重新创建表的更改问题的解决方法
- 第六届省赛C--对称博弈