博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入探究JavaScript对象系列(五)
阅读量:4521 次
发布时间:2019-06-08

本文共 2662 字,大约阅读时间需要 8 分钟。

       之前比较忙,再加上家里发生了些不开心的事情,也就没什么心情看书,昨天加了一天班,今天终于可以静下心来写点东西

一.类和原型

       在JavaScript中,类的所有实例对象都从同一个原型对象上继承属性,因此原型对象是类的核心,这个在之前几篇中已经提到过,现在我们来看两个例子,着两个例子实现了同样的效果:

1 例一: 2 function inherit(p){ /;/这个函数是用来创建对象的,之前已经写到过了 3     if(p == null) throw TypeError();  4     if(Object.create) return Object.create(p);   5  6     var t = typeof p; 7     if(t !== "object" && t !== "function") throw TypeError(); 8     function F(){}; 9     f.prototype = p;10     return new F();11 }12 13 range.methods = {14     includes : function(x){15         return this.from <= x && x <=this.to;16     },17 18     toString : function(){19         return "this is form "+this.from+" to "+this.to;20     }21 }22 23 function range(from,to){24     var r = inherit(Range.methods);25     r.from = from;26     r.to = to;27     return r;28 }29 var r = range(1,9);    r.includes(3);  //返回true30 //例二31 function Rnage(from,to){32     this.from = from;33     this.to = to;34 }35 36 Range.prototype = {37     includes : function(x){38         return this.from <= x && x <=this.to;39     },40 41     toString : function(){42         return "this is form "+this.from+" to "+this.to;43     }44 }   var r = new Range(1,9);    r.includes(22);//返回false

       上述两个例子实现了同样的效果,例一中定义了一个工厂方法range(),用来创建新的范围对象,要注意的地方是range函数给每个范围对象都定义了from属性和to属性,这两个属性是非共享的,当然也是不可继承的。(用这种方式来创建新对象的方法不常见)

       例二中使用了现在经常看到的利用构造函数来创建对象的方法,调用构造函数的一个重要特征是,构造函数的prototype属性被用来做新对象的原型。

  原型对象是类的唯一标志:当且仅当两个对象继承自同一个原型对象时,他们才属于同一个类的实例,举个例子来说,当使用instanceof来检测一个对象是否为给定类的实例时,如r instanceof Range,js引擎不是检查r是否是由Range()函数来创建,而是检查r的原型对象是不是Range.prototype.

二.constructor属性

  先看下下面这张图

  任何一个JavaScript函数都可以用来当作构造函数(但往往不会正常工作),并且调用一个构造函数是要用到函数的prototype函数的,因此除了ECMAScript5中的Function,bind()方法返回的函数外,每一个js函数都自动拥有一个prototype属性,这个属性也是一个对象包含一个唯一不可枚举的constructor属性,这个属性的值是一个函数对象(var F = function(){};),js正式用这个属性来只带它们的构造函数,用代码的方式来表现就是像下面这个样子

1 var p = F.prototype;2 var c = p.constructor;3 c === F;       //返回true

或者是像下面这样:

1 function F(){};2 var o = new F();3 o.constructor === F;  //返回true

  可能会有人拿上一节中的例二来测试constructor,结果发现是不对的,为什么不对呢?那是因为例二中Range.prototype被重写了,它根本就没有constructor属性,那怎么补救呢,很简单,可以这样写:

1 //方法一 2 Range.prototype = { 3         constructor : Range, //显式地指定constructor值 4     includes : function(x){ 5         return this.from <= x && x <=this.to; 6     }, 7  8     toString : function(){ 9         return "this is form "+this.from+" to "+this.to;10     }11 }12 13 //方法二14 Range.prototype.includes = function(x){15         return this.from <= x && x <=this.to;16 }17 Range.prototype.toString = function(x){18        return "this is form "+this.from+" to "+this.to;19 }

  关于原型继承和constructor,推荐大家看看这个,看完会有更深的理解。

转载于:https://www.cnblogs.com/iamluzhe/p/3515968.html

你可能感兴趣的文章
C语言中多维数组的内存分配和释放(malloc与free)(转)
查看>>
python random
查看>>
互联网技术
查看>>
input输入框只允许输入数字/ 数字+小数点/ 文字+字母/ 等解决方法
查看>>
【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)...
查看>>
函数名、闭包及迭代器
查看>>
mysql 5.6 参数详解
查看>>
求旋转数组的最小元素
查看>>
jQuery ajax error函数(交互错误信息的获取)
查看>>
Gson解析Json数组
查看>>
Lintcode: Fast Power
查看>>
Pocket Gem OA: Log Parser
查看>>
枚举也能直接转换为对应的数值输出
查看>>
angularjs1-7,供应商
查看>>
BitSet
查看>>
Spring常用注解,自动扫描装配Bean
查看>>
(转载)深入理解WeakHashmap
查看>>
JAVA中的数组
查看>>
爬虫—使用Requests
查看>>
scrollIntoView()窗口滚动
查看>>