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

JavaScript学习笔记——对象

2016-05-05 19:36 561 查看
对象概述

对象中包含一系列属性,这是属性是无序的。
每个属性都有一个字符串key和对应的value。

var obj = {x:1,y:2};
obj.x; //1
obj.y; //2
//能够动态的增加和删除属性

对象的key为string类型,如果访问时不为string,则会调用tostring先转成string

var obj = {};
obj[1] = 1;
document.write(obj['1']);

obj[{}] = true;
document.write(obj[{x:1}]);

对象的构造



对象的创建

1、字面量

var obj1 = {x:1,y:2};

var obj2 = {
x:1,
y:2,
o:{ //属性为对象,继续嵌套
z:3,
n:3
}
};

2、new/原型链

function foo(){};
foo.prototype.z = 3;

//使用new构造器时,obj的原型会指向foo的原型prototype对象
var obj = new foo();
obj.y = 2;
obj.x = 1;

typeof obj.toString; //'function'
toString方法是因为其原型链末端的Object对象有toString方法
'z' in obj; //true //从prototype继承而来
obj.hasOwnProperty('z'); //false //z不是obj上的属性,而是其原型链上的属性

原型链



当访问一个对象的属性时:
1、若该对象有该属性,则返回该属性
2、若该对象没有该属性,则沿着原型链向上查找:
2.1 若在该原型链上查找到该属性,则返回对应的属性值
2.2 若沿原型链查找到null时仍未找到,则返回undefined
3、若对该对象的属性进行赋值时,只会在该对象上添加或修改属性,不会修改其原型链上的属性

3.Object.create

var obj = Object.create({x:1});
obj.x //1
typeof obj.toString //"function"
obj.hasOwnProperty('x'); //false

obj的原型链为: obj --> {x:1}
--> Object.prototype -->
null

var obj = Object.create(null);
obj.toString //undefined

obj的原型链为: obj -->
null

属性操作

1.属性读写

var obj = {x:1,y:2};
obj.x; //1
obj['y']; //2

obj['x'] = 3; //赋值
obj.y = 4;

2.循环遍历
当使用for..in遍历对象的属性时,其顺序是不一定的,而且有可能将对象原型链上的属性也遍历出来
in 沿原型链向上查找,但是enumerable为false的属性不会被输出
3.属性删除

var person = {age:28,title:'fe'};
delete person.age; //true
person.age; //undefined 删除成功
delete person.age; //true 再次删除,仍然返回true,但是在严格模式下会报错

delete Object.prototype; //false prototype不允许被删除

var descriptor = Object.getOwnPropertyDescriptor(Object,'prototype'); //取prototype的描述对象
descriptor.configurable; //false 它的configurable为false,则不可配置

4.属性检测

var cat = new Object;
cat.legs = 4;
cat.name = "Kitty";

'legs' in cat; //true
'hands' in cat; //false
'toString' in cat; //true 沿原型链向上查找

cat.hasOwnProperty('legs'); //true
cat.hasOwnProperty('toString'); //false 不是对象的方法,而是原型链上对象的方法

cat.propertyIsEnumerable('legs'); //true 可枚举
cat.propertyIsEnumerable('toString'); //false 不可枚举

5.属性枚举

var o = {x:1,y:2,z:3};
"toString" in o; //true
o.hasOwnProperty("toString"); //false
for(key in o){
console.log(key); //只会输出x,y,z,因为toString等是不可枚举的
}

var son = Object.create(o);
son.a = 4;
"toString" in son; //true
son.hasOwnProperty("x"); //false
for(key in son){
console.log(key); //输出a,x,y,z 因为x,y,z是son原型链上的对象的可枚举的属性
}

//若只想遍历该对象的属性
for(key in son){
if(son.hasOwnProperty(key)){ //过滤掉原型链上的属性
console.log(key); //输出a 因为x,y,z在hasOwnProperty方法中返回false
}
}

6.getter/setter

var test = {
name : "Michael",
weibo : "794430210@qq.com",
born : 1994,
get age(){
return new Date().getFullYear() - this.born;
},
set age(val){
console.log("age cant be set to " + val);
}
}
document.write(test.age);
document.write(test.name);
document.write(test.weibo);

example:
var man = {
name:"Michael",
$age:null,
get age(){
if(this.$age == undefined){//非严格等于(null/undefined)
return new Date().getFullYear() - 1994;
} else{
return this.$age;
}
},
set age(val){
val = +val; //把val变成对应的数值,若本身为数值,则不操作
if(!isNaN(val) && val > 0 && val < 100){
this.$age = +val;
}else{
throw new Error("age is incorrect!");
}
}
}
document.write(man.age);
man.age = 120;
document.write(man.age);

function foo(){}
Object.defineProperty(foo.prototype,'z',{
get:function(){return 1;}
});
var obj = new foo();
document.write(obj.z);
obj.z = 100; //会查找原型链上的set方法,不会在obj上创建新对象
document.write(obj.z);

Object.defineProperty(obj,'z',{ //可以在obj上创建z属性
value:100,configurable:true
});
document.write(obj.z);

7.属性标签

[[configurable]]:表示能否使用delete删除,或能否修改为访问器属性,默认为true
[[enumerable]] :表示能否通过for-in遍历,默认为true
[[writable]] :表示能否修改属性的值,默认为true
[[value]] :表示该属性的数据,默认为undefined

var x = Object.getOwnPropertyDescriptor({pro:true},'pro');
x.value; //true
x.writable; //true
x.enumerable; //true
x.configurable; //true

Object.defineProperty(person,'name',{
value:'MJ', //值
enumerable:true, //可枚举,for-in
writable:false, //可修改
configurable:false //可删除
});
document.write(person.name); //MJ
person.name = "Michael"; //由于writable false 不可修改
document.write(person.name); //MJ
delete person.name; //由于configurable false 删除失败
document.write(person.name); //MJ

Object.defineProperty(person,'marry',{ //定义不可枚举的变量marry
value:false,
enumerable:false
});
document.write(Object.keys(person)); //name 返回的属性中就没有marry



8.对象标签

[[prote]] //原型标签
[[class]] //类型标签
[[extensible]] //对象是否可扩展

[[class]] 类型标签 不可以直接获取,但是可以通过Object.prototype.toString 来获取

var toString = Object.prototype.toString;
function getType(o){return toString.call(o).slice(8,-1)}

getType(null); //Null
getType(undefined); //Undefined
getType(1); //Number
getType(new Number(1)); //Number
getType(true); //Boolean

[[extensible]] 扩展标签
设置该对象是否可以继续扩展属性
var person = {x:1,y:2};
Object.isExtensible(person); //true

Object.preventExtensions(person); //阻止对象扩展属性
Object.isExtensible(person); //false
person.z = 3; //扩展属性失败
person.z; //undefined

Object.seal(person); //configurable变为false

Object.freeze(person); //writable变为false

//以上操作只针对对象,不会影响对象的原型链的属性

9.序列化、其他对象方法

var obj = {x:1,y:2,z:[1,2,3],nullValue:null};
JSON.stringify(obj); //{"x":1,"y":2,"z":[1,2,3],"nullValue":null}
!!!!有坑!!!!!
var obj1 = {x:undefined,y:NaN,z:Infinity,w:new Date()}; //属性值含有undefined、NaN、Infinity时

undefined不显示,NaN/Infinity为null
JSON.stringify(obj1); //{"y":null,"z":null,"w":"2016-05-05T04:21:00.502Z"}

var obj2 = JSON.parse{'{"x":1}'}; 将JSON对象转换成js对象
obj2.x; //1

toString 可把一个逻辑值转换为字符串,并返回结果

var obj = {x:1,y:2};
obj.toString; //[object Object]
obj.toString = function(){ //覆写toString方法
return "toString [x: " + this.x + " y: " + this.y+"]";
}
obj; //x:1 y:2
obj.toString; // x:1 y:2

valueOf 函数方法是返回指定对象的原始值

obj.valueOf= function(){ //覆写valueOf方法
return this.x + this.y;
}
+obj; //3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: