你不知道的JS读书笔记3—对象与类

关于JS对象,我觉得大家应该再熟悉不过了。下面就总结一点我不算很熟悉的,或者需要注意的知识点。然后顺便提一下传统中的类,JavaScript是怎么模拟实现的。

对象基础知识

对象,是由无序的键值对组成,而且键是字符串。如果不是字符数据类型,会自动调用toString方法转化为字符类型。

比如,

1
2
3
4
obj['1'] = 1;
obj[1] //1
obj[{}] = 2;
obj['[object Object]']; // 2

ES5中新增属性描述符,用以下方式定义对象属性:

1
2
3
4
5
6
Object.defineProperty(obj, attr, {
value: 2017, // 值
writable: false, // 可写
configurable: false, // 可配置
enumerable: false // 可枚举
})

还可以用getter,setter来定义:

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
var obj = {
get name(){
return this._name;
},
set name(val){
this._name = val;
}
};
obj.name = '2017';
obj.name; // '2017'
// 或者
Object.defineProperty(obj,'gender', {
get : function(){
return this._gender;
},
set: function(val){
this._gender = val;
} ,
configurable: true,
enumerable: true
});
obj.gender = 'female';
obj.gender; // 'female'

需要注意的是,用Object.defineProperty定义的时候,value&writable与get&set只能二者选其一。

获取属性描述,Object.getOwnPropertyDescriptor(obj, attr);

如果是obj.a = 2这种方式定义的,三个属性(可写,可配置,可枚举)默认为true;而如果是Object.defineProperty(obj, ‘a’, { value:2 })定义的话,则相反。

  • writable 为 false的话,不能被修改;
  • configurable 为false的话,不能用Object.defineProperty配置,也不能被删除
  • enumerable 为false的话,不能被枚举
    • 可以用Object.propertyIsEnumerable(obj.a)去检测
    • 在for .. in obj中,obj及其原型链上的所有可枚举的属性会被列出
    • 而.. in obj 可以获取obj及其原型链上所有的属性,包括不可枚举
    • 用obj.hasOwnProperty(‘a’)去检测这个属性是否是它本身的属性而不是在原型链上找到的
    • Object.keys(obj) 也不能获取到不可枚举的属性

P.S. ES中对数组的枚举可以用for of:

var mateArray = ['John', 'Ash', 'Rob'];
for(var item of mateArray){
    console.log(item);
}
// John
//  Ash
//  Rob

模拟类的几种方式

面向对象的编程思想给我们带来了众多好处,很多语言都支持。而JavaScript没有真正的类,我们用对象来模拟类。简单来说,对象的创建只有两种方式:字面量形式和构造函数形式。

//字面量形式
var person = {
    'name': 'Claire',
    'sayHello': function(){
        console.log('hello, my name is ' + this.name);
    }
}

// 构造函数形式
var person = new Object();
person.name = 'Claire';
person.sayHello = function(){
    console.log('hello, my name is ' + this.name);
};

因为类就是用对象模拟的,所以上面两种也是创建类的方式。由于对象具有原型属性,可以用以下的方式创建:

// 构造函数+原型形式
function Person(){
    this.name = 'Claire';
} 
Person.prototype.sayHello = function(){
    console.log('hello, my name is ' + this.name);
};

var me = new Person();

用new调用的函数,我们在JavaScript称为构造函数。构造函数其实就是一般的函数,与其他语言中的构造函数概念不同。

在《javascript高级程序设计(第二版)》中作者列出了7种方式,网上有人把它copy出来了,点击这里。眼睛看得有点花,而且我并不能很好地区别这7种。对我来说,就是以上提到的3种方式吧。

参考资料: