原型
创建新对象
Object.create(Object.prototype)
;
属性查询和设置
通过"."或方括号来获取属性的值,值得注意的是使用方括号时里面的值是以属性命名的字符串,用方括号有点类似于数组。
var age=mianmian["age"]; //获取年龄属性;
var age=mianmian.age;
继承
先看一小段代码
var o={};
o.x=1;
var p=inherit(o);
var q=inherit(p);
console.log(q.x); //1;
发现什么 了没有,就是在查找继承的时候是从下往上一层一层的查找原型的,当找到x时即返回值,停止。对象的原型属性就像一个“链”,这个链实现 属性的继承。
在js中,只有在查询属性的时候才会体会到继承的存在,而设置属性与继承无关无法通过继承的属性值的改变来改变原型的值;
var o={};
o.x=3;
var m=inherit(o);
function inherit(p) { //继承函数
if(p==null) throw TypeError();
if(Object.create) return Object.create(p);
var t=typeof p;
if(t!=="object"&&t!=="function") throw TypeError();
function f() {};
f.prototype=p;
return new f();
}
m.x=9;
console.log(o.x); //3,未改变原始值
删除属性
delete只能删除自有属性,不能删除继承属性,要删除继承属性必须从定义这个属性的原型对象上删除它,而且会影响所有继承自这个原型的对象
function Mianmian(name,age) {
this.name=name;
this.age=age;
}
Mianmian.prototype={
sum:function(a,b) {
return a+b;
},
divide:function(a,b) {
return a/b;
}
};
var mianmian=new Mianmian("xiaomian",19);
delete(Mianmian.prototype.sum); //删除原型属性
console.log(mianmian.sum) //undefined,,继承对象的属性随之改变
检测属性
in
:如果对象的自有属性或继承属性中包含这个属性就返回true
var o={x:1};
"x" in o; //true
"toString" in o; //true
hasOwnproperty
:检测给定名字是否为对象的自有属性,对于继承属性返回false
propertyIsEnumerable
:检测是自有属性并且这个属性可枚举时才返回true
还有一个是!==
判断一个属性是否为undefined,如果为undefined的话就返回false,这样的话使用跟in
有点相似,但是呢,如果一个对象的值为undefined的话就会出现差异。
var m={a:undefined};
console.log(m.a in m); //false
console.log("a" in m); //true
console.log(m.a!==undefined); //false
console.log("a"!==undefined) //true
枚举属性
for/in 循环可在循环中遍历对象中可枚举的属性,包括自有属性和继承属性。对象中的内置方法是不可枚举的,但在代码中添加的属性是可枚举的。为了避免枚举一些不可用参数,可以用
var m={x:2,y:{a:1,b:2}};
for(var p in m)
{
if(!m.hasOwnProperty(p)||typeof m[p]==="function")continue; //除去继承属性和方法
console.log(p);
}
属性getter和setter
不是很会。待补充
属性的特性:
value,writable(可写性),enumerable(可枚举性),configurable(可配置性)
要想设置属性的特性,或者想让新建属性具有某种特性,需要调用Object.defineproperty(),传入要修改的对象,要创建或修改的属性名称以及属性描述符对象
var o={};
Object.defineProperty(o,"x",{value:1
writable:true,
enumerable:false,
configurable:true});
console.log(o.x); //1
Object.defineProperty(o,"x",{writable:false});
o.x=2; //操作失败
console.log(o.x); //1
可配置的意思就是你还可以通过以下的方式改变值
Object.defineProperty(o,"x",{value:2});
console.log(o.x); //2
如果不可配置的话就会是这样
var p=Object.defineProperties({},{
x:{value:1,writable:false,enumerable:true,configurable:false},
y:{value:8,writable:false,enumerable:true,configurable:true}
});
Object.defineProperty(p,"x",{value:8}); //报错
对于新创建的属性来说,默认的特性值是false或undefined,这个方法要么修改已有属性要么新建自有属性,但不会改变继承属性。
通过Object.defineProperties()可同时修改或创建多个属性,就像包含多个小对象一样,如:
var p=Object.defineProperties({},{
x:{value:1,writable:true,enumerable:true,configurable:true},
y:{value:8,writable:false,enumerable:true,configurable:true}
});
p.x=9
console.log(p.x); //9
p.y=3;
console.log(p.y) //8
可拓展性
一般来说,所有的内置对象和自定义对象都是可拓展的,但是可以通过Object.preventExtensions()
和Object.seal()
将其设置为不可拓展的,但是一旦转为不可拓展就不能再转换为可拓展的了,Object.esExtensible()
检测对象是否可拓展,seal()
检测对象是否封闭
比较:
1 .
var o={x:1,y:3};
Object.seal(o);
o.a=1;
console.log(Object.isSealed(o)); //true
2 .
var o={x:1,y:3};
Object.preventExtensions(o);
o.x=2; //2
console.log(Object.isExtensible(o)); //false
3 .
var o={x:1,y:3};
Object.seal(o);
o.a=1;
console.log(Object.isExtensible(o)); // false
4 .
var o={x:1,y:3};
Object.preventExtensions(o);
o.a=1;
console.log(Object.isSealed(o)); //false
这说明Object.seal()
是比Object.preventExtensions()
更严格的锁定对象,并且他们都可以修改原先属性中的值,暂时还没了解到其中的区别,另外还有一个Object.freeze()
函数则是更更严格的锁定对象,他连属性中的值都不能改变