1.javascript创建对象 new原型链
function foo(){
}
foo.prototype.z=3;
var obj=new foo();
obj.x=1;
obj.y=2;
obj.z=5;
console.log(obj.x);//1
console.log(obj.z);//5
console.log(typeof obj.toString());//string类型
console.log(obj.hasOwnProperty("z"));//false
for(var x in obj){
console.log(obj[x]);//1 2 5
}
obj.z=undefined;
console.log(obj.z);//5
console.log(delete obj.z);//true,删除直接复制的变量
console.log(obj.z);//3
console.log(delete foo.prototype.z);//true
console.log(obj.z);//undefined
如上面的代码所示,如果通过直接赋值的方式给对象中的属性赋值,访问的话,输出的不是原型链上增加的属性,obj.z的值是5,但是如果没有obj.z=5;的话,会输出3,因为此时访问的是通过prototype增加的属性值,即原型链上的值。但是如果已经赋值的情况下要访问原型链上的属性,必须用delete操作符将变量删除,再次访问的话就是访问的原型链上的值。。
2.对象创建-Object.create()
var obj=Object.create({x:1});
console.log(obj.x);//原型链上的属性
console.log(typeof obj.toString);//function
console.log(obj.hasOwnProperty("x"));//false
var obj1=Object.create(null);
console.log(typeofobj1.toString);//undefined
如上面代码所示,可以通过Object.create()的方式创建对象,相当于通过原型链的方式创建属性,让新创建的对象obj的原型指向创建的参数,这是从原型链上继承的,而不是对象本身的属性。
3.javascript属性获取
var obj={};
console.log(obj.y);//undefined
console.log(obj.y.z);//语法错误typeError
obj.y.z=3;
console.log(obj.y.z);
4.javascript属性删除
var person={age:28,title:'fe'};
console.log(delete person.age);//true
console.log(delete person["title"]);//true
console.log(person.age);//undefined
console.log(delete person.age);//true
console.log(person.age); //undefined
console.log(delete Object.prototype);//false
var descriptor=Object.getOwnPropertyDescriptor(Object,'prototype');
descriptor.configurable;//false
如上图所示,有一些属性是不允许被删除的,比如Object.prototype,看上图的最后两行代码,获取到Object.prototype属性,然后它的configurable的值为false,所以不允许使用delete 操作符删除
5.属性的检测
var cat=new Object();
cat.legs=4;
cat.name="kitty";
console.log('legs' in cat);//true
console.log('abc' in cat);//false
console.log('toString' in cat);//true,从原型链上继承的属性 console.log(cat.hasOwnProperty('legs')); console.log(cat.hasOwnProperty('toString')); console.log(cat.propertyIsEnumerable('legs'));//true,可枚举 console.log(cat.propertyIsEnumerable('toString'));false,//不可枚举
其中,propertyIsEnumerable()属性是用来判断此对象是否包含某个属性,并且这个属性是否可枚举的,需要注意的是:如果判断的属性存在于Object对象的原型内,不管它是否可枚举都会返回FALSE。。可枚举性决定了这个属性能否被for…in查找遍历到
下面,我们还可以自定义一个对象的属性,让其enumerable的值为FALSE,
Object.defineProperty(cat,'price',{enumerable:false,value:1000});
cat .propertyIsEnumerable('price');//false
cat.hasOwnProperty('price');//true
通过以上可以知道,Object中的defineProperty()方法可以自定义一些属性,并且可以指定该属性是否可枚举,定义的属性通过hasOwnProperty()都可以访问到。。
6.属性的枚举
var o={x:1,y:2};
console.log('toString' in o);//true
console.log(o.propertyIsEnumerable('toString'));//false
for(var key in o){
console.log(o[key]);
}
var obj=Object.create(o);//继承原型链上的属性
obj.a=4;
for(var key1 in obj){
console.log(obj[key1]);//1 2 4
}
for(var key2 in obj){
if(obj.hasOwnProperty(key2)){
console.log(obj[key2]);//4
}
}
其中,hasOwnProperty()只是遍历得到对象上的属性,而for…in可以遍历得到对象上定义的以及原型链上的属性。。。
7.可以为已定义的对象定义一系列属性以及属性标签–defineProperty()方法
var person={};
Object.defineProperty(person,'name',{
configurable:false,
writable:false,
enumerable:true,//可以通过Object.keys()访问到
value:'xue'
});
console.log(person.name);//xue
person.name=1;//writable值为false,所以修改不成功
console.log(person.name);//xue
console.log(delete person.name);//configurable属性为FALSE,所以删除不成功
Object.defineProperty(person,'type',{
configurable:true,
writable:true,
enumerable:false,//不可以通过Object.keys()访问到
value:'object'
});
Object.keys(person);//["name"]
通过上面的代码可以看出,用这个方法定义了两个属性,一个name,一个type,其中name的ebumerable属性值为true,所以
可以通过Object.keys()方法得到,但是属性type的值为false,所以不可以通过这个方法遍历得到。
我们也可以通过defineProperties()定义多个属性。。
var person={};
Object.defineProperties(person,{
title:{value:'fe',enumerable:true},salary:{value:5000,enumerable:true,writable:true}
}) console.log(Object.getOwnPropertyDescriptor(person,'salary'));//{value: 5000, writable: true, enumerable: true, configurable: false}
由此可见,getOwnPropertyDescriptor()可以查看属性字段的值,对于未定义的属性默认为false。。
8.有关原型链的详细介绍
观察上面两幅图片,发现有如下关系:
bosn.proto=Student.prototype;
Student.prototype.proto=Person.prototype;
Persosn.prototype.proto=Object.prototype;
Object.prototype.proto=NULL;
因此在调用这些方法的时候,要根据原型链的关系一层一层的向上查找,比如bosn.walk()方法,向上查找bosn的原型链发现Student.prototype上面没有walk()方法,接着再向上寻找,发现Person.prototype上面有walk()方法直接调用这个方法就行了。。