通常点语法读取对象属性的方式为
Object.name1.name2 ...
,可以一直链下去提供一个全局函数,读取对象属性
function property(name, object)
,这样的的话,函数为主体,对象object
作为函数的一个参数。name
为name1.name2 ...
的链式结构创建一个独立的文件
property.js
,模块导出这个函数,使用的时候,直接就是全局函数的样子了。
function property(name, object) {
var name = String(name);
return name === '_'
? object
: name.split('.').reduce((pre, cur) => pre && pre[cur], object);
}
module.exports = property;
- 当然,对于这种直接返回一个函数的导出形式,可以更简单一点,直接写。
module.exports = function property(name, object) {
var name = String(name);
return name === '_'
? object
: name.split('.').reduce((pre, cur) => pre && pre[cur], object);
}
上面的代码,自定义了一个特殊字符
'_'
,直接返回对象object
本身name
是由.
连接起来的一个链式,所以用String
的split()
函数按照.
切换成一个数组,然后通过数组的reduce
函数,返回了对象的另外一种形式。读取对象
object
的属性name
的值,可以通过object.name
的形式,也可以通过object[name]
的形式。并且object[name]
适应性(或者说容错性)更强,这是JavaScript
语言的一个特性。在
reduce
的函数参数中pre && pre[cur]
利用了JavaScript
的特性:如果两个操作数都是对象,那么返回第二个操作数
所以这段代码和用[]
访问对象属性是等价的。简单讲
property
函数的输入是:name1.name2.name3... , object
;输出是:object[name1][name2][name3][...]
可以写一个测试的
property_test.js
(和property.js
在同一目录)在Visual Studio Code中运行一下,看看效果。
const property = require('./property.js')
const log = console.log;
// 直接定义的对象
const person = {
age : 29,
name : 'xiao ming',
birthday : {
year : 2011,
month : 8,
day : 20,
},
address : 'shang hai',
isMarried : true,
wife : 'xiao hong',
true : false,
undefined : null,
null : 'hello',
}
log(property('age', person)); // 29
log(property(true, person)); // false
log(property(undefined, person)); // 'null'
log(property(null, person)); // 'hello'
log(property(`birthday.day`, person)); // 20
log(property('isMarried', person)); // true
log(property('wife', person)); // 'xiao hong'
log(property(`_`, person)); // 对象本身
// 通过构造函数创建对象
function User(name) {
this.name = name;
this.age = 18;
this[1] = 'ok';
this[200] = `year`;
}
var user = new User('user1');
log(property(`name`, user)); // 'user1'
log(property(`age`, user)); // 18
log(property(`1`, user)); // 'ok'
log(property(200, user)); // `year`
log(property(`_`, user)); // 对象本身
从运行结果看,基本符合预期。对于
true, undefined, null, 200
这些异常的name
,也有一定的转化能力