let obj = {
name : 'sena'
};
console.log(obj.name) // 'sena'
console.log(obj[name]) // undefined
我们需要了解关于他们的一些限制
.运算符
: 右侧必须是一个属性名称命名的简单标识符
[]
: 右侧必须是一个计算结果为字符串的表达式
先复习一下JS中的标识符:
标识符
- 在JS中所有的可以由我们自主命名的都可以称为是标识符
- 例如:变量名、函数名、属性名都属于标识符
- 命名一个标识符时需要遵守如下的规则:
1.标识符中可以含有字母 、数字 、下划线_ 、$符号
2.标识符不能以数字开头
3.标识符不能是ES中的关键字或保留字
4.标识符一般都采用驼峰命名法 - JS底层保存标识符时实际上是采用的Unicode编码,
所以理论上讲,所有的utf-8中含有的内容都可以作为标识符
嗯,这里就可以看出.的缺陷了,如果对象中的属性刚好不符合标识符的规范,就不能用.来访问
比如说:
let obj = {"1" : 123}
console.log(obj.1); // Uncaught SyntaxError: Unexpected number
let obj1 = {"star gf" : 'sion'};
console.log(obj1.star gf); //Uncaught SyntaxError
所以这里只能用[]
let obj = {"1" : 123}
obj["1"] // 123
let obj1 = {"star gf" : 'sion'};
console.log(obj1['star gf']); // sion
然后我们再来看看[]
[]右边必须是一个计算结果为字符串的表达式,这给了[]非常强大的功能
let target = 'name';
let obj3 = {
name : 'sena'
};
//使用变量
console.log(obj3[target]); //sena
如果[]里面不是一个表达式,而是一个原始值或者对象,事情就开始变得有意思起来了,总结了一下规律大概就是下面两个
1、 如果里面的是一个原始值,那么就直接把原始值变成相应的字符串(0 -> ‘0’ , true -> ‘true’ , null -> ‘null’, undefined -> ‘undefined’)(值得注意的是不是调用相应包装类原型上的toString()
,而且undefined和null也没有包装类)
2、如果里面的不是一个原始值,那么就调用toString变成字符串
/*调用toString的情况*/
let obj1 = {
'name' : 'sena',
'true' : 'sion',
};
let obj2 = {
toString(){
return 'name';
}
};
let arr5 = [];
arr5.toString = function(){ //将数组转化为字符串
return 'name';
};
function fun() {
return 'name';
}
fun.toString = function () {
return 'name';
};
console.log(obj1[obj2]); //sena
console.log(obj1[fun]); //sena
console.log(obj1[arr5]); //sena
/*直接转化的情况*/
let obj3 = {
"undefined" : 1,
"null" : 2,
"true" : 3,
"1" : 4,
'name' : 'sena'
};
/*重写了包装类的原型toString*/
Boolean.prototype.toString = function(){
return 'name';
};
console.log(obj3[1]); //4
console.log(obj3[true]); //3 这里可以证明没有调用包装类上的toString
console.log(obj3[null]); //2
console.log(obj3[undefined]); //1