浅谈JavaScript中的伪类 (李睿豪)
来源:互联网 发布:python mysql事务回滚 编辑:程序博客网 时间:2024/05/06 07:04
最近研究了一下JavaScript中的类,JS中的类还是很奇葩的,是伪类,类的实现是基于其原型继承机制的。写出来和大家分享一下!
一.JS类的建立方式是怎么样呢?它有哪几种建立方式呢?
(1).通过原型建立
function MyCreate(pro){if (pro === null) {throw TypeError();}if (Object.create) {return Object.create(pro);}var newV = function(){};var thisType = typeof pro;if(thisType !== 'function' && thisType !== 'object')throw TypeError();newV.prototype = thisType;return new newV();//在new 后的函数当成构造函数,通过new 创建对象}function NumberFW(fir_num,sec_num){var newDX = MyCreate(NumberFW.methods);newDX.from = fir_num;newDX.to = sec_num;return newDX;}NumberFW.methods = {includes:function(x){return this.from <= x && x <= this.to;},foreach:function(fun){if(typeof fun != 'function')throw TypeError();for(var i = this.from;i <= this.to; i++)fun(i);return this;}};
在JS中,类的所有实例对象都是从同一个原型对象上继承属性。因此,原型对象是类的核心!上面是一个通过原型建立的模型实例,MyCreate()函数是解决一些不支持Object.create浏览器的功能函数,它接受一个参数,返回以参数为原型的一个实例对象,在NumberPW函数中,接收两个参数,以NumberPw.methods为原型,创建一个newDX对象,然后初始化它返回!
需要注意的是:上面的例子中,原型属性作为函数的一个属性存储,它定义了所有“范围对象"所共享的方法!
(2).通过构造函数
使用关键字new来调用构造函数,使用new调用构造函数会自动创建一个新对象,此构造函数的作用只是初始化这个新对象。 还有必须要清楚地就是:通过构造函数创建对象会继承构造函数的prototype属性,也就是构造函数的prototype会当作新对象的原型。通过同一构造函数创建的对象的原型都相同,继承相同的属性。
说了这么多废话,来给大家看个实例:
<script type="text/javascript">function MyCreate(fir_num,sec_num){this.from = fir_num;this.to = sec_num;//不需要返回} MyCreate.prototype = {includes: function(x){return this.from <= x && x <= this.to;},foreach: function(fun){for(var i = this.from; i <= this.to;i++)fun(i);return this;}}//用new 创建的对象会 以 函数的prototype属性为原型,会继承它</script>
MyCreate()是构造函数,值得注意的一点:构造函数的首字母要大写~ 通过构造函数创建的对象的原型是构造函数对象的prototype属性。
总结:通过new在构造函数调用之前已经创建了对象,实际上,构造函数只是当作只是当作新对象的一个方法调用的一次。那么构造函数的使命就是初始化这个新对象,所用使用this来初始化对象,注意,使用构造函数并不需要返回什么,因为它只是当作新对象的一个方法来初始化新对象!
(3)极简主义
<span style="font-size:12px;"><script type="text/javascript">var Animal = {createNew: function(){var animal = {};animal.sleep = function(){console.log("打呼噜!");}return animal;}};var Cat = {likeEat : "fish", //公共共享的属性,只会被创建一次createNew: function(){var catVol = "喵喵喵" //<span style="color:#FF0000;">私有变量,其实就是只有在构造函数中才可以控制他,构造函数外不可操作它!</span>var cat = Animal.createNew(); <span style="color:#FF0000;">//继承!</span>cat.voice = function(){console.log(catVol);};cat.eatSome = function(){console.log("I like eat " + Cat.likeEat);};cat.setFood = function(food){Cat.likeEat = food;}return cat;}};</script></span>这种方式创建类,非常简单,上文例子中有Animal对象和Cat对象,他们都有createNew方法,每次只需要调用他们就可以创建一个实例对iang,createNew方法有一个特点,就是创建一个空对象,然后再函数里初始化它,最后返回它。 上面代码中有一个catVol,他是一个私有变量,通过闭包控制他,只有通过这个新对象的特权方法才能访问他!
二.子类的使用
(1).举个例子,如果B是A的子类,那么首先要确保B的原型对象继承A的原型对象。
function MyCreate(pro){if (pro === null) {throw TypeError();}if (Object.create) {return Object.create(pro);}var newV = function(){};var thisType = typeof pro;if(thisType !== 'function' && thisType !== 'object')throw TypeError();newV.prototype = thisType;return new newV();//在new 后的函数当成构造函数,通过new 创建对象}function Son(firstName,years){this.firstName = firstName;this.years = years;}function Father(lastName){this.lastName = lastName;}Father.prototype = {getName: function(){return this.firstName;}};Son.prototype = MyCreate(Father.prototype);//通过这样的给Son.prototype赋值,不会破坏Father.prototype的封装!Son.constructor = Son;
<span style="color:#FF0000;"><strong>Son.prototype = MyCreate(Father.prototype);Son.constructor = Son;<span style="color:#000000;">这两行是核心代码,让Son.prototype是以Father.prototype为原型对象,并且第二句意思是让Son.constuctor属性在指回Son构造函数!</span></strong></span>(2).另一种方法
function Son(firstName,years){this.firstName = firstName;this.years = years;}function Father(lastName){this.lastName = lastName;};Father.prototype = {getName: function(){return this.firstName + this.lastName},};var try_this = new Father("li");Son.prototype = try_this;Son.prototype.constructor = Son; Father.prototype.getYear= function(){ return this.years; }; try_this.lastName = "Smile"; var me = new Son("ruihao",20);var you = new Son("jiahua",19);第二张方法的核心代码:
var try_this = new Father("li");
Son.prototype = try_this;
Son.prototype.constructor = Son;
这样确实可以!需要注意的是,无论创建多少次新的Son对象,这个Father只会创建一次,它又是Son的prototype ,所以会被所有的Son继承并且共享变量!
这里更新Father.prototype,因为是动态的,并且将 Father的一个实例赋值给Son.prototype,其实赋的是 引用!!!
me you这些实例的原型是Son.prototype,也就是Father的一个实例,但是在修改me you 这些实例中继承来的lastName时候,Father的那个实例确实不会修改,个人感觉,就是把Father 那个实例的属性浅复制到me 和 you 中!!
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
作者: 李睿豪 2015.11.22
- 浅谈JavaScript中的伪类 (李睿豪)
- 浅谈JavaScript之"伪类"
- 浅谈 CSS 中的伪类 after
- 浅谈JavaScript中的事件
- Javascript中的Var浅谈
- 浅谈javascript中的全局变量
- 浅谈javascript中的prototype
- 浅谈JavaScript中的prototype
- 浅谈JavaScript中的原型模式
- Javascript中的sort()语法浅谈
- 浅谈javascript中的加减时间
- 浅谈javascript中的defer、async
- 浅谈javaScript中的闭包
- 浅谈javascript中的constructor属性。
- 浅谈JavaScript中的原型prototype
- Javascript中的apply()、call()以及伪数组
- 浅谈CSS的伪类与伪元素
- 【javascript】浅谈javascript中的对象和类型
- Swift笔记
- EM算法推导
- Android Service生命周期及用法!
- ThinkPHP学习-2
- swift笔记2
- 浅谈JavaScript中的伪类 (李睿豪)
- hihocoder1257(构造)(2015北京ACM/ICPC)
- MyBatis 初始配置
- android之View坐标系(view获取自身坐标的方法和点击事件中坐标的获取)
- 知原理(2)
- 多校连萌 简单的求和
- 你需要明白的SQL SERVER书签查找(Bookmark Lookup)
- 苏州OJ c005: 二叉树遍历
- Bmob云的使用_快速入门