javascript之Object

了解Object的常用方法

先看下Object的所有方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
var objectNames = Object.getOwnPropertyNames(Object);
console.log(objectNames)
/*
[ 'length',
'name',
'prototype',
'assign',
'getOwnPropertyDescriptor',
'getOwnPropertyDescriptors',
'getOwnPropertyNames',
'getOwnPropertySymbols',
'is',
'preventExtensions',
'seal',
'create',
'defineProperties',
'defineProperty',
'freeze',
'getPrototypeOf',
'setPrototypeOf',
'isExtensible',
'isFrozen',
'isSealed',
'keys',
'entries',
'values' ]
*/

var objectAllNames = Object.getOwnPropertyNames(Object.prototype);
console.log(objectAllNames)
/*
[ 'constructor',
'__defineGetter__',
'__defineSetter__',
'hasOwnProperty',
'__lookupGetter__',
'__lookupSetter__',
'isPrototypeOf',
'propertyIsEnumerable',
'toString',
'valueOf',
'__proto__',
'toLocaleString' ]
*/

Object.defineProperty(foo, ‘fullName’, {})用于设置一个对象的属性值和描述符,描述符有4个:

[[Configurable]],

[[Enumerable]], 是否可以foreach,stringify

[[Writable]],

[[Value]]

Object.getOwnPropertyDescriptor(foo, ‘fullName’); 可以取得给定属性的描述符

isPrototypeOf是用来判断要检查其原型链的对象是否存在于指定对象实例中,是则返回true,否则返回false。

obj.hasOwnProperty(“属性名”);//实例obj是否包含有圆括号中的属性,是则返回true,否则是false

所有继承了Object.prototype的对象都会从原型链上继承到hasOwnProperty方法,这个方法检测一个对象是否包含一个特定的属性,和in不同,这个方法会忽略那些从原型链上继承的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var o =new Object();
o.prop="exists";
function change(){
o.newprop=o.prop;
delete o.prop;
}
o.hasOwnProperty("prop")//true
change()//删除o的prop属性
o.hasOwnProperty("prop")//false
//删除后在使用hasOwnProperty()来判断是否存在,返回已不存在了

var o =new Object();
o.prop="exists";
o.hasOwnProperty("prop");//true 自身的属性
o.hasOwnProperty("toString");//false 继承自Object原型上的方法
o.hasOwnProperty("hasOwnProperty");//false 继承自Object原型上的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 只有对象才有__proto__属性。
// 类才有prototype属性。
// __proto__是指向prototype的指针。
// prototype: 挂载了: 类的自身方法,constructor, __proto__

// 万事万物皆对象。类也是一个对象。如function() {} 是 Function的实例对象
// there is a class named Class

// Object.assign(target, source1, source2) === target 合并对象

var foo = {
firstName: 'daejong',
lastName: 'dottie',
get fullName() {
return this.firstName + " " + this.lastName;
}
};

console.log(foo.fullName);

// 对foo升级,
// 1.支持middleName属性
// 2.在JSON.stringify(foo)时fullName属性不被序列化
Object.defineProperty(foo, 'fullName', {
configurable: true, //为了可以重新配置Object.defineProperty(foo, 'fullName', desrciptor);
get: function() {
var fullName = this.firstName;
if (this.middleName) {
fullName += " " + this.middleName;
}
fullName += " " + this.lastName;
return fullName;
}
});

Object.defineProperty(foo, 'name', {
get: function() {
return 'ni hao';
}
});

console.log(foo.name);

// delete foo.name 可以删除属性

foo.middleName = 'ai';
console.log(foo.fullName);
//"daejong ai dottie"


console.log(JSON.stringify(foo));
//{"firstName":"daejong","lastName":"dottie","fullName":"daejong ai dottie","middleName":"ai"}


// bug: fullName仍被序列化了。
// 于是检查fullName的属性描述其
console.log(Object.getOwnPropertyDescriptor(foo, 'fullName'));
//{get: function fullName(){...}, set:undefined, enumerable:true, configurable:true}
// 发现enumerable为true

// 自运行函数,变量有自己的作用域。
// 故修改如下:
(function() {
var desrciptor = Object.getOwnPropertyDescriptor(foo, 'fullName');
desrciptor.enumerable = false;
Object.defineProperty(foo, 'fullName', desrciptor);
})();

console.log(JSON.stringify(foo))

call和apply方法(Function的方法)

都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

var aaaa = function() {}
console.log(aaaa.call === Function.prototype.call) // true

function add(c,d){
return this.a + this.b + c + d;
}

var s = {a:1, b:2};
console.log(add.call(s,3,4)); // 1+2+3+4 = 10
console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14

// 截取网上的一段代码示例:
// 例1
<script>
window.color = 'red';
document.color = 'yellow';

var s1 = {color: 'blue' };
function changeColor(){
console.log(this.color);
}

changeColor.call(); //red (默认传递参数)
changeColor.call(window); //red
changeColor.call(document); //yellow
changeColor.call(this); //red
changeColor.call(s1); //blue
</script>

//例2
var Pet = {
words : '...',
speak : function (say) {
console.log(say + ''+ this.words)
}
}
Pet.speak('Speak'); // 结果:Speak...

var Dog = {
words:'Wang'
}

//将this的指向改变成了Dog
Pet.speak.call(Dog, 'Speak'); //结果: SpeakWang