关于JS对象,我觉得大家应该再熟悉不过了。下面就总结一点我不算很熟悉的,或者需要注意的知识点。然后顺便提一下传统中的类,JavaScript是怎么模拟实现的。
对象基础知识
对象,是由无序的键值对组成,而且键是字符串。如果不是字符数据类型,会自动调用toString方法转化为字符类型。
比如,
ES5中新增属性描述符,用以下方式定义对象属性:
还可以用getter,setter来定义:
需要注意的是,用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种方式吧。
参考资料:
- https://github.com/getify/You-Dont-Know-JS 你不知道的JS(上卷)
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty MDN defineProperty
- 《javascript高级程序设计(第二版)》
- https://gold.xitu.io/entry/58291447128fe1005cd41c52 JavaScript 创建对象的 7 种方法