javascript --- 原型初探七日谈(一)
在javascript中,像原型,闭包这样的概念,只要我们能领悟其中的原理,一切都会显得格外清晰与明了。
原型属性(prototype):
下面我们简单定义一个函数
function her(a, b){return a + b; }
在这些函数一定义就被赋予的属性中,就包括prototype属性,她的初始化是一个空对象:
typeof her.prototype // Object
当然我们也可以自己添加该属性:
her.prototype = {};
而且我们可以赋予这个空对象一些属性和方法,这并不会对foo函数产生神马影响,以为只有her()函数被当做构造函数来使用的情况下,这些属性才起作用。
来个例子:
function her(){this.name = 'Anna',this.child = 'Jok',this.say = function(){return 'My name is' + this.name + 'My child is' + this.child;} }
上面是一个简单的构造函数,我们就用构造器属性prototype属性来增加她的属性和方法,您可以这样:
her.prototype.sex = 'women'; her.prototype.height = '175cm'; her.prototype.doing = function(){return 'I is a' + this.sex + 'I am height is' + this.height; }
使用原型的属性和方法:
var she = new her(); she.name; // Anna she.child; // Jok
如上所讲如果想用以上的属性和方法,那必须new一个上述构造函数her()的一个对象实例。
对于原型来说,最重要的一点就是理解她的‘实时性’,由于在javascript中几乎所有对象都是通过引用的方式传递的。因此我们创建出来的新对象并没有属于自己的原型副本。这也就意味着我们可以随时修改prototype的属性和方法,并且由同一构造函数创建出来所有对象的prototype都会同时改变。 (甚至还会影响到修改之前就已经创建好的对象)。
继续之前的例子:
her.prototype.eat = 'water'; she.eat; // water
哪怕she之前就被创建了,我仍然还会在这个对象中访问到eat属性。
自身属性与原型属性
上述的创建doing()方法那个示例,其实直接引用一次her.prototype也可以完成上述工作:
function her(){this.name = 'Anna',this.child = 'Jok',this.say = function(){return 'My name is' + this.name + 'My child is' + this.child;},this.sex = 'women',this.eat = 'water' }
her.prototype.doing = function(){return 'I is a' + her.prototype.sex + 'I am height is' + her.prototype.height; }
这样有神马不同吗?要想知道这个问题就必须深入了解原型的工作原理。
var she = new her();
当我们访问she对象的某个属性时,例如she.name时,javascript引擎会遍历该对象的所有属性,并查找出name属性,如果找到了就会直接返回,否则为undefined.
这回我们访问she.sex会发生神马呢,javascript引擎依旧会查询she的所有属性,但是这回找不到一个叫sex的属性了,接下来javascript引擎就会去查找用于创建该对象的构造函数的原型(等价于我们直接访问到she.constructor.prototype),如果在原型中找到了该属性,就立刻使用该属性。
这种方式与直接访问原型属性是一样的。每个对象都有属于自己的构造器属性,这个属性引用的就是创建该对象的构造函数,所以:
she.constructor === her; // true she.constructor.prototype.sex; // women
现在,我们回顾一下整个过程。我们知道每个对象都有一个构造器,而原型本身也是一个对象,必然也会有自己的构造器,而这个构造器又会有自己的原型。于是这种结构会一直持续下去,并取决于原型链的长度。她们的最后一环必然是Object()内建对象,她是最高级的父及对象(始祖)。
she.toString(); // Object
利用自身属性重写原型属性
通过上述我们知道一个对象自身属性中没有找到指定的属性,前提是这个属性存在,那么她就会顺着原型链去找。但是遇到对象的自身的属性和原型属性重名怎么办呢?
答案是自身属性的优先级要高于原型属性(自己的利益至上)。
来个梨子:
function her(){this.name = 'Anna'; } var she = new her(); she.name = 'Lous'; she.name; // Lous
我们可以通过hasOwnProperty()方法来判断一个属性是自身属性还是来自于原型属性。
she.hasOwnProperty('name'); // true
如果这时候我们把自身属性删掉,那么同名的原型属性又会浮出水面:
delete she.name; //trueshe.name // Annashe.hasOwnProtype('name') // false
当然我们可以重建这个属性:
she.name = 'Lous'; she.name; // Lous; she.hasOwnProtype('name'); // true
如何判断一个属性到底是原型链中那个原型的属性呢?答案还是用hasOwnProperty()属性。例如我们想知道toString()这个方法来自与哪里:
she.hasOwnProperty('toString'); // false she.constructor.hasOwnProperty('toString'); // false she.constructor.prototype.hasOwnProperty('toString'); // false Object.hasOwnProperty('toString'); // false Object.prototype.hasOwnProperty('toString'); // true
呵呵(*Φ皿Φ*)!!
对象的枚举属性
如果想要获得一个对象的所有属性的列表,那么就用for-in循环吧!(for循环适合数组,for-in循环更适合对象),来个栗子:
var params = {name : 'Anna',sex : 'women' }var url = 'http://www.baidu.com?',i,query = []; for(i in params){query.push(i + '=' + params[i]); } url += query.join('&'); // 'http://www.baidu.com?name=Anna&sex:women';
在这里有几个细节需要注意:
1. 不适所有的对象属性都是可以枚举的,例如length,constructor等就不会被显示,那些会显示的属性被称为可枚举的,我们可以通过各个对象所提供的propertyIsEnumerable()方法来判断对象的某个属性是不是可枚举的。
2. 原型链中的各个属性也会被显示出来,当然她们是被可枚举的。
来个栗子:
function her(){this.name = 'Anna';this.sex = 'women';this.say = function(){'My name is' + this.name;} } var she = new her(); she.eat = 'water';for(var i in she){console.log(i + '=' + she[i]); }name = 'Anna' sex = 'women' say = function(){'My name is' + this.name;} eat = 'water'
我们再来一次,这次输出自身属性
for(var i in she){if(she.hasOwnProperty(i)){console.log(i +'='+she[i]);} }name = 'Anna' sex = 'women' say = function(){'My name is' + this.name}
未完待续。。。。。。
转载于:https://www.cnblogs.com/beyond-succeed/p/5819328.html
javascript --- 原型初探七日谈(一)相关推荐
- 深入解析JavaScript 原型继承
JavaScript 原型继承,学习js面向对象的朋友可以看看.十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Object.prototype Ja ...
- 深入理解 JavaScript 原型
前言 原型,作为前端开发者,或多或少都有听说.你可能一直想了解它,但是由于各种原因还没有了解,现在就跟随我来一起探索它吧.本文将由浅入深,一点一点揭开 JavaScript 原型的神秘面纱.(需要了解 ...
- JavaScript原型与原型链(总结篇)
系列文章推荐 JavaScript原型与原型链(基础篇) JavaScript原型与原型链(进阶篇) JavaScript原型与原型链(总结篇) 1 构造函数和实例对象 构造函数的prototype属 ...
- 深入理解javascript原型和闭包(16)——完结
之前一共用15篇文章,把javascript的原型和闭包. 首先,javascript本来就"不容易学".不是说它有多难,而是学习它的人,往往都是在学会了其他语言之后,又学java ...
- Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance) 收藏 前面我们看到了如何使用 constructor 来初始化对象.如果这样做,那么每一个创建的新对象都会对 ...
- 深入理解javascript原型和闭包(17)——补this
本文对<深入理解javascript原型和闭包(10)--this>一篇进行补充,原文链接:http://www.cnblogs.com/wangfupeng1988/p/3988422. ...
- 深入理解javascript原型和闭包(3)——prototype原型
既typeof之后的另一位老朋友! prototype也是我们的老朋友,即使不了解的人,也应该都听过它的大名.如果它还是您的新朋友,我估计您也是javascript的新朋友. 在咱们的第一节(深入理解 ...
- 深入理解javascript原型和闭包(2)——函数和对象的关系
上文(理解javascript原型和作用域系列(1)--一切都是对象)已经提到,函数就是对象的一种,因为通过instanceof函数可以判断. var fn = function () { }; co ...
- JavaScript 原型中的哲学思想
欢迎来我的博客阅读:「JavaScript 原型中的哲学思想」 记得当年初试前端的时候,学习JavaScript过程中,原型问题一直让我疑惑许久,那时候捧着那本著名的红皮书,看到有关原型的讲解时,总是 ...
最新文章
- 【camera】基于YOLO的车辆多维特征识别系统(车色,车品牌,车标,车型)与PYQT实现(课程设计)
- xp主机用VMware9和10安装Ubuntu12.04后无法进入图像界面
- 图解Oracle 12c 手动建库
- 点击EditText外部区域失去焦点的方法
- vb.net2019-下载文件
- 简单的脚本控制面试题
- 阿里云服务网格ASM集成SLS告警
- Boring Partition(CF-239D)
- 移植性问题のerror C2664: strcpy : 不能将参数 2 从 CString 转换为 const char *怎么回事?...
- 计算机模拟求解流体力学方程,计算流体力学模拟(CFD模拟)FLUENT中的湍流模型(一)...
- ourdev 学习arm先看看,工具和软件分析
- 苹果电脑的文件怎么复制到移动硬盘,macbook文件怎么拷贝到移动硬盘
- mysqlpump备份工具简单使用
- 重磅!IEEE Fellow周礼栋担任微软全球资深副总裁
- oracle之归档日志空间管理
- 小程序(倒计时的制作)
- 怎样恢复手机oracle默认窗口,EBS登陆后的第一页面恢复成默认都显示WorkList
- [bugku]web后面的部分 【脚本,正则 md5 】(疯狂补题qaq) 重点是搞会了 而不是写博客 m...
- 使用Docker构建服务(6)
- 针对X5新内核Blink以及google chrome主要字体主动放大问题