单纯的if判定,可能存在key存在但值是undefined
let obj={ key: undefined };
obj["key"] !==undefined // false 但是key是存在的!
“property” in obj 可以判断一个对象是否有原生属性或者原型属性;
let obj={ key: undefined };
"key" in obj // true
如果要检查键是否不存在,请记住使用括号:
let obj={ key: undefined };
!("key" in obj)
!"key" in obj
obj.hasOwnProperty(“property”) 返回布尔类型,用于判断某个对象上是否有某个属性,但是仅仅指的是实例化的属性,不包括原型上的属性,也不包括属性指向一个对象当中的属性
日常开发中,作为一个JavaScript开发者,我们经常需要检查对象中某个键是否存在。这看似简单,但其实有多种方法可供选择,每种方法都有其独特之处。本文将介绍几种检查JavaScript对象键的方法,并比较它们的性能。
假设我们有一个简单的对象:
const user={
name: 'John',
age: 30
};
我们想在访问name键之前检查它是否存在:
if (user.name) {
console.log(user.name);
}
这个方法表面上看没问题,但如果name键存在但值是undefined会怎样呢?
const user={
name: undefined
};
if (user.name) {
// 这段代码不会执行!
}
直接访问一个不存在的键会返回undefined,但是访问值为undefined的键也是返回undefined。所以我们不能依赖直接键访问来检查键是否存在。
一种常见的方法是使用typeof来检查类型:
if (typeof user.name !=='undefined') {
console.log(user.name);
}
typeof会对不存在的键返回"undefined",对存在的键返回其它类型,如"string"。然而,这种方法有几个缺点:
in操作符允许我们检查键是否存在于对象中:
if ('name' in user) {
console.log(user.name);
}
这种方法比typeof更简洁:
但是,in操作符也会检查对象的原型链。因此它对原型链上存在的键也会返回true。
要仅检查对象自身的键,可以使用hasOwnProperty:
if (user.hasOwnProperty('name')) {
console.log(user.name);
}
这种方法只会返回对象自身拥有的键,而不会检查继承的属性:
缺点是hasOwnProperty需要方法调用,在性能关键的代码中可能会有影响。
哪种方法最快呢?以下是直接键访问、in、hasOwnProperty和typeof的简单性能比较:
const user={
name: 'John'
};
let key='name';
function directAccess() {
return user[key] !==undefined;
}
function inOperator() {
return key in user;
}
function hasOwnProperty() {
return user.hasOwnProperty(key);
}
function typeofCheck() {
return typeof user[key] !=='undefined';
}
function objectKeysCheck() {
return Object.keys(user).includes(key);
}
// 运行每个函数100万次
let start=performance.now();
for (let i=0; i < 1000000; i++) {
directAccess();
}
console.log(`directAccess took ${performance.now() - start} ms`);
start=performance.now();
for (let i=0; i < 1000000; i++) {
inOperator();
}
console.log(`inOperator took ${performance.now() - start} ms`);
start=performance.now();
for (let i=0; i < 1000000; i++) {
hasOwnProperty();
}
console.log(`hasOwnProperty took ${performance.now() - start} ms`);
start=performance.now();
for (let i=0; i < 1000000; i++) {
typeofCheck();
}
console.log(`typeofCheck took ${performance.now() - start} ms`);
start=performance.now();
for (let i=0; i < 1000000; i++) {
objectKeysCheck();
}
console.log(`objectKeysCheck took ${performance.now() - start} ms`);
结果如下( 测试机器:apple m1 ,内存16G):
如上所示,inOperator 运算显著快于其他方法。
在大多数情况下,in操作符在可读性和性能之间提供了最佳平衡。只有在需要排除继承键时才使用hasOwnProperty。
理解这些不同方法的细微差别是检查JavaScript键的关键。根据具体需求选择合适的工具,除非性能至关重要,否则应优先考虑可读性。
效果图:
2 html骨架:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--网页标题-->
<title>detection</title>
<!--内部css部分-->
<style>
......
</style>
</head>
<body>
<!--div部分-->
<div class="contain">
......
</div>
<!--内部js部分-->
<script>
......
</script>
</body>
</html>
3 css部分:
<!--内部css部分-->
<style>
/*网页和body整体设置*/
html,body{
margin:0;
padding:0;
/*网页背景颜色设置*/
background-color: rgb(96, 94, 212);
}
/*class='contain'在css的前面有点*/
.contain{
width:200px;
height: 200px;
font-size:25px;
text-align: center;
position: absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
z-index:30;
}
/*警示label和结果label*/
.alertInfo,.resultInfo{
color:rgb(12, 231, 213);
font-weight: bold;
/*可以写在这里,注意数字和px紧紧相邻*/
width: 350px;
height: 10px;
}
/*输入框的设置*/
.text{
width:150px;
/*文本框默认显示,下面就是不显示*/
/*outline:none;*/
text-align: center;
font-size:25px;
color:blue;
}
/*显示框的设置*/
.show{
font-size:25px;
color:red;
}
</style>
4 body的div部分:
<!--div部分-->
<div class="contain">
<!--注意:style可以嵌套在里面,但不推荐,也可以单独写在上面的css内-->
<!--p class="alertInfo" style="width: 350px; height: 10px">显示倒5个字符串的输入框:</!--p-->
<p class="alertInfo" >显示倒5个字符串的输入框:</p>
<!--placeholder是指输入框默认显示文字-->
<input type="text" class="text" placeholder="请输入内容">
<!--p class="resultInfo" style="width: 350px; height: 10px">显示倒4个字符串的显示区:</!--p-->
<p class="resultInfo" >显示倒4个字符串的显示区:</p>
<p class="show"></p>
</div>
5 body的js=JavaScript=script部分:
<!--内部js部分-->
<script>
// 被let声明的变量不会作为全局对象window的属性,而被var声明的变量却可以
//text和show均是class,所以前面有一个点
let input=document.querySelector(".text");
let show=document.querySelector(".show");
input.addEventListener('keyup',debounce(handle,100));
// 防抖处理
function debounce(func,wait){
let timeflag;
return function(){
clearTimeout(timeflag); //清除100ms之内之前触发的定时器。
let arg=arguments;
let timethis=this;
timeflag=setTimeout(func.bind(timethis,arg),wait);
}
}
//回调函数
function handle(){
//输入框内倒取5个字符串
input.value=input.value.slice(-5);
//输入框内倒取4个字符串
show.textContent=input.value.slice(-4);
}
</script>
6 html部分基础学习,自己整理并分享出来。
*请认真填写需求信息,我们会在24小时内与您取得联系。