文档章节

javascript原型和多维数组遍历

指尖残雪
 指尖残雪
发布于 2016/05/22 23:56
字数 1372
阅读 7
收藏 0
点赞 2
评论 0
我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
原型对象实际就是一个构造函数的实例对象,与普通的实例对象没有什么本质上的区别,js中每一个对象都有一个原型对象。不过他比较特殊,该对象所包含的所有属性和方法能够供构造函数的所有实例共享,这就是其他语言所说的继承,而javascript通过原型对象来实现继承,简称原型继承。静态原型继承:Object.prototype.[method field] ;
isPrototypeOf(实例对象) 判断原型的方法
ECMA5: Object.getPrototypeOf():根据实例对象获得原型对象
object.hasOwnProperty(attribute) 判断属性是否属于对象本身
in 操作符 判断对象中是否存在该属性(无论是实例对象还是原型对象)
ECMA5新特性 Object.keys();拿到当前对象里的所有keys 返回一个数组

ECMA5新特性 Object.getOwnPropertyNames 枚举对象所有的属性 :不管该内部属性能否被枚举


代码示例:

function Person(){                                    
	                                                  
}                                                     
var obj = Person.prototype;                           
alert(typeof obj);                                    
obj.name = 'z3';                                      
obj.age  = 20 ;                                       
obj.sayName = function(){alert(this.name);};          
var p1 = new Person();                                
var p2 = new Person();                                
alert(p1.age);                                        
alert(p2.age);                                        
p1.sayName();                                         
p2.sayName();                                         
alert(p1.sayName == p2.sayName)
obj是Person的原型,p1和p2使用共同的原型。alert(p1.sayName == p2.sayName)  输出结果为true;

构造函数.prototype =  原型对象   
原型对象.constructor = 构造函数  

alert(obj.constructor);   

输出结果:

function Person(){        
                     
}                         

实例对象 prototype 是 原型对象    

isPrototypeOf(new instance); 判断原型的方法

alert(obj.isPrototypeOf(p1));  //obj是p1的原型



ECMA5: Object.getPrototypeOf():根据实例对象获得原型对象

function Person(){                                                           
	                                                                         
}                                                                            
                                                                             
Person.prototype.name = 'z3';                                                
Person.prototype.age  = 20 ;                                                 
Person.prototype.sayName  = function(){alert('我是原型对象的方法!')};                 
                                                                             
                                                                             
var p1 = new Person();                                                       
alert(p1.name); // z3                                                        
var prototypeObj = Object.getPrototypeOf(p1);                                
alert(prototypeObj == Person.prototype);
输出z3和true;

每次代码读取一个对象的属性的时候: 首先会进行一次搜索:搜索实例对象里name的属性,看看有没有,如果没有,再去p2的实例所对应的原型对象里去搜索name属性 如果有就返回 没有返回undefined     

var p2 = new Person();                      
p2.name = 'w5';		// 实例对象的name                                        
alert(p2.name);		// 就想获得原型对象的name属性
输出w5,我们把p2.name删除掉

var p2 = new Person();                      
p2.name = 'w5';		// 实例对象的name            
delete p2.name ;                            
alert(p2.name);		// 就想获得原型对象的name属性
输出z3
判断一个对象属性 是属于原型属性 还是属于实例属性

function Person(){                                            
	                                                          
}                                                             
                                                              
Person.prototype.name = 'z3';                                 
Person.prototype.age  = 20 ;                                  
Person.prototype.sayName  = function(){alert('我是原型对象的方法!')};  
var p3 = new Person();                
//p3.name = 'z6';                     
alert(p3.name);                       
alert(p3.hasOwnProperty('name'));
输出结果:z3和false。由于我们把p3.name = 'z6';  注释掉以后,name是属于原型属性。p3.name = 'z6';是属于实例属性。

in 操作符 判断属性是否存在于 实例对象和原型对象中 

function Person(){                                           
	                                                         
}                                                            
                                                             
Person.prototype.name = 'z3';                                
Person.prototype.age  = 20 ;                                 
Person.prototype.sayName  = function(){alert('我是原型对象的方法!')}; 
var p1 = new Person();                     
alert('name' in p1); // true               
var p2 = new Person();                     
p2.name = 'w3';                            
alert('name' in p2); // true
都输出true,说明in 操作符 判断属性是否存在于 实例对象和原型对象中 

通过以上方法我们可以自己写一个方法,断一个属性是否存在原型中 

当不属于实例属性只属于原型属性时候返回true。

// 在原型对象中 是否存在这个属性 第一个参数:当前对象 ,第二个参数:要判断的属性                          
                                                                     
function hasPrototypeProperty(object , name){                        
	return !object.hasOwnProperty(name) && name in object ;          
}                                                                    
                                                                     
var p3 = new Person();                                               
//p3.name = 'xiao A';                                                  
alert(hasPrototypeProperty(p3,'name'));
p3.name = 'xiao A';    注释后name是只属于原型中,所以返回true,当不注释的时候,name是实例属性,返回false

ECMA5新特性 Object.keys();  拿到当前对象里的所有keys 返回一个数组 

var p1 = new Person();               
p1.name = 'z3';                      
p1.age = 20 ;                        
                                     
var attributes = Object.keys(p1);    
alert(attributes);
输出:name,age

var attributes2 = Object.keys(Person.prototype); 
alert(attributes2);
输出:name,age,sayName

ECMA5 constructor属性: 该属性是不能被枚举的[eable = false]       
如果想要被枚举,使用Object.getOwnPropertyNames,枚举对象所有的属性 :不管该内部属性能否被枚举   

var attributes3 = Object.getOwnPropertyNames(Person.prototype);    
alert(attributes3);
输出:constructor,name,age,sayName


一维数组的遍历:

ECMA5 forEach 循环遍历数组的每一项(只适合遍历一维数组)

var arr = [1,2,3,[4,5]];                        
arr.forEach(function(item , index , array){   
	alert(item);                              
});
输出:

1

2

3

4,5

自己实现一个Array each方法 能遍历多维数组  

var arr = [1,2,3,[4,[5,[6]]]]; // arr.length                                        
                                                                                    
Array.prototype.each = function(fn){                                                
	try{                                                                            
		//1 目的: 遍历数组的每一项 //计数器 记录当前遍历的元素位置                                          
		this.i || (this.i=0);  //var i = 0 ;                                        
		//2 严谨的判断什么时候去走each核心方法                                                     
		// 当数组的长度大于0的时候 && 传递的参数必须为函数                                               
		if(this.length >0 && fn.constructor == Function){                           
			// 循环遍历数组的每一项                                                           
			while(this.i < this.length){	//while循环的范围                            
				//获取数组的每一项                                                          
				var e = this[this.i];                                               
				//如果当前元素获取到了 并且当前元素是一个数组                                            
				if(e && e.constructor == Array){                                    
					// 直接做递归操作                                                      
					e.each(fn);                                                     
				} else {                                                            
					//如果不是数组 (那就是一个单个元素)                                            
					// 这的目的就是为了把数组的当前元素传递给fn函数 并让函数执行                               
					//fn.apply(e,[e]);                                              
					fn.call(e,e);                                                   
				}                                                                   
				this.i++ ;                                                          
			}                                                                       
			this.i = null ; // 释放内存 垃圾回收机制回收变量                                      
		}                                                                           
		                                                                            
	} catch(ex){                                                                    
		// do something                                                             
	}                                                                               
	return this ;                                                                   
}                                                                                   
                                                                                    
arr.each(function(item){                                                            
	alert(item);                                                                    
});

© 著作权归作者所有

共有 人打赏支持
指尖残雪
粉丝 7
博文 73
码字总数 0
作品 0
上海
后端工程师
5 分钟掌握 JavaScript 实用窍门

简评:一开始 JavaScript 只是为网页增添一些实时动画效果,现在 JS 已经能做到前后端通吃了,而且还是年度流行语言。本文分享几则 JS 小窍门,可以让你事半功倍 ~ 1. 删除数组尾部元素 一个...

⋅ 06/07 ⋅ 0

由js数组类型判断触发的浪漫思绪

一、前言 众所周知,js是门“动态”、“弱类型”编程语言,这意味着在js中可以很任性的定义变量,任性的同时也意味着需常在开发中对变量做类型判断,曾几何时,对数组变量的类型的判断是件很...

hanmin ⋅ 06/08 ⋅ 0

JS高级之面试必须知道的几个点

深圳市人人聚财招前端啦 ~~~ 招前端,招前端,招前端,欢迎扫描加群,砸简历过来: 前言 这段时间突然发现JS原生好多东西都忘记了,但有些东西确实很重要,所以又重新再梳理一次。主要有函数的...

小小小 ⋅ 06/08 ⋅ 0

JavaScript 编程精解 中文第三版 六、对象的秘密

六、对象的秘密 原文:The Secret Life of Objects 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2 版)》 抽象数据类型是通过编写一种特殊的...

ApacheCN_飞龙 ⋅ 05/04 ⋅ 0

浅谈 instanceof 和 typeof 的实现原理

typeof 实现原理 一般被用于判断一个变量的类型,我们可以利用 来判断, , , , , , 这七种类型,这种判断能帮助我们搞定一些问题,比如在判断不是 object 类型的数据的时候,能比较清楚的告诉...

nicole_zhang ⋅ 05/28 ⋅ 0

Lynx技术分析-JS引擎扩展设计

JS Binding 技术 Lynx(一个高效的跨平台框架) 的 JS Binding 技术最主要的目的是搭建一个高效的与 JS 引擎解耦的通信桥梁,同时具备 JS 引擎切换的能力。该技术经历了多次迭代,最终通过抽...

hxxft ⋅ 05/15 ⋅ 0

code-rhythm:写了个vscode扩展,让代码更有快感

项目地址 Github - onvno/code-rhythm 原因 写代码本身是件快乐的事情,但开发中总有各种烦恼。 有时候一个很简单的方法,因为不确定传参的形式,不确定返回形式,不确定具体用法,就得翻墙,...

onvno_ ⋅ 06/07 ⋅ 0

5分钟掌握JavaScript小技巧

译者按: 技巧虽好、重在掌握并使用起来! 原文: Learn these neat JavaScript tricks in less than 5 minutes 译者: Fundebug 为了保证可读性,本文采用意译而非直译。另外,本文版权归原作...

Fundebug ⋅ 05/22 ⋅ 0

5分钟,掌握9个风骚又简洁的JavaScript技巧

5分钟,掌握9个风骚又简洁的JavaScript技巧 编辑于 2018-05-08

优达学城(Udacity) ⋅ 05/16 ⋅ 0

这一次,我们换种姿势学习 javascript

前言 《你不知道的 javascript》是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途。本书介绍了该系列的两个主题:“作用...

程序员解决师 ⋅ 05/29 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)

之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长...

颖辉小居 ⋅ 15分钟前 ⋅ 0

利用有限制通配符提升API灵活性(28)

1、参数化类型是不可变的 List<String> 不是List<Object>的子类,但是二者是有联系的 利用有限制的通配符类型处理类似情况 List<? extends Object>(生产者) Collection<? super E>(消费者......

职业搬砖20年 ⋅ 21分钟前 ⋅ 0

ssm框架 +bootstrap分页

这里有两种方式 方式一:自己写分页 方式二:使用插件PageHelper 1.自己写分页 1.1 效果 1.2 实现过程 1.2.1 创建分页公共类 //---------------------------1.属性-------------------------...

Lucky_Me ⋅ 28分钟前 ⋅ 0

Istio

helm template install/kubernetes/helm/istio --name istio --namespace istio-system > $HOME/istio.yaml after $ kubectl create namespace istio-system$ kubectl create -f $HOME/ist......

openthings ⋅ 29分钟前 ⋅ 0

内核线程、轻量级进程、用户线程

线程与进程概念 在现代操作系统中,进程支持多线程。 进程是资源管理的最小单元; 线程是程序执行的最小单元。 即线程作为调度和分配的基本单位,进程作为资源分配的基本单位 一个进程的组成...

117 ⋅ 34分钟前 ⋅ 0

elasticsearch2.4.6升级为elasticsearch-5.5.0的经历

将elasticsearch-5.5.0 中的配置 path.data 指向原来的数据路径 即 path.data: /usr/local/src/elasticsearch-2.4.6/data 注意: elasticsearch-5.5.0 需要将jdk版本升级到1.8...

晨猫 ⋅ 34分钟前 ⋅ 1

lvm讲解 磁盘故障小案例

1

oschina130111 ⋅ 38分钟前 ⋅ 0

那些提升开发人员工作效率的在线工具

本文转载自公众号 Hollis 作为一个Java开发人员,经常要和各种各样的工具打交道,除了我们常用的IDE工具以外,其实还有很多工具是我们在日常开发及学习过程中要经常使用到的。 Hollis偏爱使用...

时刻在奔跑 ⋅ 51分钟前 ⋅ 0

restful风格 实现DELETE PUT请求 的web.xml的配置

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframe......

泉天下 ⋅ 56分钟前 ⋅ 0

Shell数组

Shell数组 Shell在编程方面比Windows批处理强大很多,无论是在循环、运算。 bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数...

蜗牛奔跑 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部