1、可枚举和不可枚举
遍历实例上的属性和方法。关键点:私有遍历,公有不遍历。
先看一个例子:
Object.prototype.aaa = function () { };
var obj = { name: '张三', age: 7 };
for (var key in obj) {
console.log(key);
}
图解: 打印结果:
【代码解释】定义了一个类为Object的实例obj,obj有私有属性name、age,为类添加公有属性/方法aaa。利用for(key in obj)打印obj中的属性/方法。打印的结果包含私有、公有。
【附加说明】
1.每一个实例都自带一个__proto__属性,值是指向所在类的原型(prototype)。
2.每一个类都自带一个属性:prototype,值为一个对象。
3.prototype都自带一个属性constructor(构造函数),属性值是当前类本身。
4.Object.prototype上没有__proto__这个属性
【两种方式只遍历私有】
扫描二维码关注公众号,回复:
2877415 查看本文章
for in 在循环遍历的时候,默认把自己私有的和在它所属类原型上扩展的属性和方法都可以遍历到。但是一般情况,我们遍历一个对象只需要私有的即可,可以通过以下判断进行处理:
方式一
Object.prototype.aaa = function () { };
var obj = { name: '张三', age: 7 };
for (var key in obj) {
if (obj.propertyIsEnumerable(key)) {
console.log(key);
}
}
方式二(使用最多)
var obj = { name: '张三', age: 7 };
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key);
}
}
打印结果都是:
2、Object.create
var obj = {//堆内存xxxfff000
constructor: Fn,
getX: function () {
}
};
function Fn() {
}
Fn.prototype = obj;//堆内存xxxfff000
var f = new Fn;
Fn.prototype.sum=function(){
}
上面这个例子的问题是:如果改变了Fn.prototype的内容,obj也相应改变。这样是不好的,因为我们只是想把obj的内容拷贝给Fn.prototype。如何修改Fn的原型,不修改obj,是接下来讨论的问题。
克隆对象
第一种方法:定义一个空对象,遍历所有私有属性与方法赋值给空对象
var obj = {//堆内存xxxfff000
constructor: Fn,
getX: function () {
}
};
var obj2={};
for(var key in obj){
if (obj.hasOwnProperty(key)) {
obj2[key]=obj[key];
}
}
第二种方法(推荐):创建一个对象obj3,还要把obj作为这个对象obj3的原型。在IE6,7,8不兼容(ECMScript5)
var obj = {
constructor: Fn,
getX: function () {
}
};
var obj3=Object.create(obj);
Object.create效果
var obj = {
getX: function () {
}
};
var obj2=Object.create(obj);
obj2.getX();//obj2通过原型找到getX
obj.getY=function(){
console.log("2");
};
//obj增加,obj2的原型也增加
obj2.getY();//obj2通过原型找到getY
自己也可以模拟Object.create功能,也是可以达到一样的效果(可以兼容IE6,7,8)
var obj = {
getX: function () {
}
};
function object(o){
function Fn(){
}
Fn.prototype=o;
return new Fn;
}
var obj2=object(obj);
未完待续