JavaScript中对象的属性值可以使用.来获取,也可使用[]包裹属性名来获取。
一般来说两种方法都适用于直接获取属性值。
但是如果是使用变量作为属性值,或者是通过for in 来遍历对象,使用.来得到属性值就行不通了。
例如,定义一个对象:
let user={
name:"ProKingDU",
pass:"**************",
age:19,
sex:"雄",
}
简单输出一下某一个属性的值:
console.log(user.name);
console.log(user['name']);
很明显,使用.来获取属性值直接跟随属性名就可以,但是如果是[]就需要使用字符串包裹属性名。
所以如果是通过变量来获取属性:
console.log(user[name]);
let name='pass';
console.log(user.name);
console.log(user[name]);
这段代码很有意思,第一个打印输出会报出一下错误:
load.html?_ijt=vegm8pr379k771cgojn6td2700:44 Uncaught ReferenceError: Cannot access 'name' before initialization
at load.html?_ijt=vegm8pr379k771cgojn6td2700:44:22
(anonymous) @ load.html?_ijt=vegm8pr379k771cgojn6td2700:44
如果注释第一句,则变量下面两段代码都是正常执行,但是值不相同,第一句输出name属性的值,第二句才输出pass属性的值。
所以得出一条教训:
尽量不要让命名重复,无论是属性还是变量,亦或者方法名,这可能产生意想不到的离谱错误!
因为在作用域内不允许在一个变量声明之前就调用它,如果你没有声明这个变量,并且在某处使用了他,会产生两种情况:
1.报错
Uncaught ReferenceError: aaaa is not defined
at load.html?_ijt=vegm8pr379k771cgojn6td2700:51:17
2.得到undefined
例如:
console.log(test);
console.log(test+1);
这时候变量test并不存在,所以会产生错误。
console.log(user.myvar);
console.log(typeof myvar);
这两种是特殊情况,都得到undefined,第一句是因为:这里获取对象属性没有使用myvar这个变量,他本来就不存在,且对象没有myvar这个属性,所以得到undefined,而第二句,一个不存在的变量,或者被声明但是没有赋值的变量都是undefined。不存在的变量没有值,且类型为undefined,被声明没有赋值的变量,值和类型都是undefined。
因为第一种情况与变量无关,所以可以得出:
当变量没有被赋值或者定义时默认的类型是undefined。
然后接着尝试遍历以上对象:
for (const key in user) {
// console.log(user.key)
}
很明显,这是一种错误的做法,因为上面已经解释了,通过.调用对象的属性是直接使用属性名,而不会选择对应的变量。
这段代码不会报错,但是会得到undefined。因为在user对象中key属性不存在。
接下来:
for (const key in user) {
console.log("属性:"+key+",值:"+user[key]);
}
这段代码就可以很好的输出对象的所有键值对,因为Key是一个变量,储存对象当前的属性,实际上就是一个字符串,而通过数组风格来访问属性值,所需要的键也是一个字符串形式,所以能够得到属性值。
那么我非要使用.来遍历应该怎么做?
首先改写一下上面的输出吧!
console.log(`属性:${key},值:${user[key]}`);
没错,通过``和${}实现格式化字符串。
我尝试这样:
for (const key in user) {
console.log(`user.${key}`);
}
却意外的得到了:
于是:如果将上面的四个结果直接写进代码里面,就能成功得到属性的值了啊!
立马想到eval()!
for (const key in user) {
console.log(eval(`user.${key}`))
}
妙啊!!!!!!!
同样可以获取到值并且保存到变量里面:
for (const key in user) {
key === 'pass' ? pass=eval(`user.${key}`) : key;
}
console.log(pass);
在扩展一下思路:
在PHP中,可以通过变量名作为函数名引用来实现动态调用函数。
例如:
$name=$_POST['name'};
$name();
以上例子是一个简单的通过POST请求调用函数的代码。
而在js或者Python中,一切皆对象,这样做明显不可能。
python:
def add(a, b):
return a + b
name = "add"
name(1.5)
js:
let a="test";
function test(){
console.log('success');
}
a();
分别报错:
Traceback (most recent call last):
File "D:\项目代码\Pycode\GPT\main.py", line 15, in <module>
name(1.5)
TypeError: 'str' object is not callable
load.html?_ijt=vegm8pr379k771cgojn6td2700:69 Uncaught TypeError: a is not a function
at load.html?_ijt=vegm8pr379k771cgojn6td2700:69:5
php:
function test(){
echo 'ssuccess';
}
$a='test';
$a();
结果:
虽然js和python有闭包和匿名函数来将函数封装到变量内,但我就是不想这样做,并且我还要能够通过变量动态的调用不同的函数。
仍然可以通过eval完成。
js:
let a="test";
function test(){
console.log('success');
}
function sec(){
console.log('ok')
}
eval(`${a}()`);
a='sec';
eval(`${a}()`);
结果:
python:
def add(a, b):
return a + b
name = "add"
def floor(a, b):
return int(a / b)
print(eval("%s(1,3)" % name))
name="floor"
print(eval("%s(5,2)" % name))
当然,这样也就自己玩个乐呵,eval很多情况下都是被禁用的函数,因为如果对外业务会存在很严重的注入漏洞,比sql注入还严重的那种!!!!!
如果是在要用,一定要前后写好变量内容过滤!
结果:
Comments NOTHING