單純的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小時內與您取得聯系。