Javascript笔记之对象

1.对象的结构:

对象中包含一系列属性,这些属性是无序的。每个属性都有一个字符串key和对应的value。对象有2种访问方式,如下图所示:

var obj = {};
obj[1] = 1;
obj['1'] = 2;
obj; // Object {1: 2}

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

2.创建对象的方式

2.1.通过字面量的方式来创建对象,如下图所示,那么访问对象的时候就可以通过obj2.z的方式来访问

var obj2 = {
    x : 1,
    y : 2,
    o : {
        z : 3,
        n : 4
    }
};

2.2.通过new/原型链的方式来创建对象,通过继承的方式来创建对象,下面的代码中,foo相当于父类,obj相当于子类,foo中定义了z属性,当在子类访问一个子类中未定义的属性时,会向上查找,查找父类中的prototype属性中是否存在该属性,能够查找到该属性,但是这个属性并不属于子类。

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

//创建对象
var obj =new foo(); obj.y = 2; obj.x = 1; obj.x; // 1 obj.y; // 2 obj.z; // 3 typeof obj.toString; // ‘function' 'z' in obj; // true obj.hasOwnProperty('z'); // false

 

 

 但是当子类中重新定义prototype中对应的属性时,obj.hasOwnProperty()函数就返回true,删除属性的时候就只能删除自身定义的属性,不能删除父类中定义的属性

obj.z = 5;
obj.hasOwnProperty('z'); // true
foo.prototype.z; // still 3
obj.z; // 5
obj.z = undefined;
obj.z; // undefined
delete obj.z; // true
obj.z; // 3

2.3通过Object.create方式创建对象,如下面的代码所示,这种 方式和上面的方式是有一点不同的,具体看下面的图。

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

 

3.属性操作的几种方式

 3.1属性读写,属性读写一般有2种方式,数组或者通过运算符.来读写属性,如下面的代码所示,一般用运算符.但是出现一次顺序排列的key时,推荐采用数组的形式来访问对象。

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

obj["x"] = 3;
obj.y = 4;

var obj = {x1 : 1, x2 : 2};
var i = 1, n = 2;

for (; i <= n; i++) {
    console.log(obj['x' + i]);
}

这里,还要注意一个小小的坑,就是用for来对 对象进行遍历时,enumrable属性为false的对象是不会出现在遍历列表中的。

var p;
for (p in obj) {
    console.log(obj[p]);
}

还要一个写代码的小技巧是,在对对象访问时候,先判断该对象是否为空,是否具有该属性

var obj = {x : 1};
obj.y; // undefined
var yz = obj.y.z; // TypeError: Cannot read property 'z' of undefined
obj.y.z = 2; // TypeError: Cannot set property 'z' of undefined

所以推荐下面的方式来访问,先做判断:

var yz;
if (obj.y) {
    yz = obj.y.z;
}

var yz = obj && obj.y && obj.y.z;

3.2 属性删除,直接用delelte删除对象的属性,configurable为false的属性不能删除,如下图中的Object.prototype

var person = {age : 28, title : 'fe'};
delete person.age; // true
delete person['title']; // true
person.age; // undefined
delete person.age; // true

delete Object.prototype; // false,

var descriptor = Object.getOwnPropertyDescriptor(Object, 'prototype');
descriptor.configurable; // false

3.3 属性检测,通过属性检测可以判断对象中存不存在对应的属性,通过hasOwnProperty()或者propertyIsEnumerable()方法来判断, 如下图中代码所示:

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

'legs' in cat; // true
'abc' in cat; // false
"toString" in cat; // true, inherited property!!!


cat.hasOwnProperty('legs'); // true
cat.hasOwnProperty('toString'); // false

cat.propertyIsEnumerable('legs'); // true
cat.propertyIsEnumerable('toString'); // false

通过Object.defineProperty()方法可以自定义对象的属性,如下图中代码所示:

Object.defineProperty(cat, 'price', {enumerable : false, value : 1000});
cat.propertyIsEnumerable('price'); // false
cat.hasOwnProperty('price'); // true

接下来说明!=与!==的区别,如下图中所示,!=模式下,undefined与null相同,但在!==严格模式下,undefined与null不同

 3.4 属性枚举,主要用在用for来遍历对象中的属性时,如下图的代码,propertyIsEnumerable属性为false的属性在遍历时,不会被遍历出来。 Object.keys(person)来遍历对象中的key也是一样的

var o = {x : 1, y : 2, z : 3};
'toString' in o; // true
o.propertyIsEnumerable('toString'); // false
var key;
for (key in o) {
    console.log(key); // x, y, z
}

var obj = Object.create(o);
obj.a = 4;
var key;
for (key in obj) {
    console.log(key); // a, x, y, z
}

var obj = Object.create(o);
obj.a = 4;
var key;
for (key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(key); // a
    }
}

4.getter和setter介绍

 若对象中的某些属性,不想暴露,可以使用set,get方式来进行属性访问,如下图的代码所示:

var man = {
    name : 'Bosn',
    weibo : '@Bosn',
    get age() {
        return new Date().getFullYear() - 1988;
    },
    set age(val) {
        console.log('Age can\'t be set to ' + val);
    }
}
console.log(man.age); // 27
man.age = 100; // Age can't be set to 100
console.log(man.age); // still 27

还有更复杂一点的set 和get方式,

var man = {
    weibo : '@Bosn',
    $age : null,
    get age() {
        if (this.$age == undefined) {
            return new Date().getFullYear() - 1988;
        } else {
            return this.$age;
        }
    },
    set age(val) {
        val = +val;
        if (!isNaN(val) && val > 0 && val < 150) {
            this.$age = +val;
        } else {
            throw new Error('Incorrect val = ' + val);
        }
    }
}

console.log(man.age); // 27
man.age = 100;
console.log(man.age); // 100;
man.age = 'abc'; // error:Incorrect val = NaN

get和set 方式还可以和原型链进行结合,将帮助我们更好地理解对象的属性

function foo() {}
Object.defineProperty(foo.prototype, 'z',   {get : function(){return 1;}});

var obj = new foo();
obj.z; // 1
obj.z = 10;
obj.z; // still 1
Object.defineProperty(obj, 'z', {value : 100, configurable: true});
obj.z; // 100;
delete obj.z;
obj.z; // back to 1
var o = {};
Object.defineProperty(o, 'x', {value : 1}); // writable=false, configurable=false
var obj = Object.create(o);
obj.x; // 1
obj.x = 200;
obj.x; // still 1, can't change it
Object.defineProperty(obj, 'x', {writable:true, configurable:true, value : 100});
obj.x; // 100
obj.x = 500;
obj.x; // 500

5.属性标签

这里主要介绍通过Object.getOwnPropertyDescriptor( )方法来获取对象的属性的标签

Object.getOwnPropertyDescriptor({pro : true}, 'pro');
// Object {value: true, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor({pro : true}, 'a'); // undefined

当需要同时定义多个属性时候,可以通过Object.defineProperties()方式,如下图所示:

Object.defineProperties(person, {
    title : {value : 'fe', enumerable : true},
    corp : {value : 'BABA', enumerable : true},
    salary : {value : 50000, enumerable : true, writable : true},
    luck : {
        get : function() {
        return Math.random() > 0.5 ? 'good' : 'bad';
        }
    },
    promote : {
        set : function (level) {
            this.salary *= 1 + level * 0.1;
        }
    }
});

Object.getOwnPropertyDescriptor(person, 'salary');
// Object {value: 50000, writable: true, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(person, 'corp');
// Object {value: "BABA", writable: false, enumerable: true, configurable: false}
person.salary; // 50000
person.promote = 2;
person.salary; // 60000

下面这张图详细描述了属性标签

7.序列化和对象方法

通过JSON.stringify()方法来让对象序列化,通过JSON.parse()方法来是json字符串转换为json对象。

var obj = {x : 1, y : true, z : [1, 2, 3], nullVal : null};
JSON.stringify(obj); // "{"x":1,"y":true,"z":[1,2,3],"nullVal":null}"

obj = {val : undefined, a : NaN, b : Infinity, c : new Date()};
JSON.stringify(obj); // "{"a":null,"b":null,"c":"2015-01-20T14:15:43.910Z"}"

obj = JSON.parse('{"x" : 1}');
obj.x; // 1

通过 字符串+对象的方式可以自动调用对象的toString()或者valueOf()方法,如下图中代码所示:

var obj = {x : 1, y : 2};
obj.toString(); // "[object Object]"
obj.toString = function() {return this.x + this.y};
"Result " + obj; // "Result 3", by toString

+obj; // 3, from toString

obj.valueOf = function() {return this.x + this.y + 100;};
+obj; // 103, from valueOf

"Result " + obj; // still "Result 3"

 

转载于:https://www.cnblogs.com/zdjBlog/p/11536450.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值