您的位置:首页 > Web前端 > JavaScript

javascript原型和多维数组遍历

2016-05-22 00:00 447 查看
我们创建的每一个函数都有一个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);
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: