Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有办法重构此代码以提高性能?_Javascript_Html_Node.js - Fatal编程技术网

Javascript 有没有办法重构此代码以提高性能?

Javascript 有没有办法重构此代码以提高性能?,javascript,html,node.js,Javascript,Html,Node.js,所以我有这个问题要做练习。代码可以工作,但我希望提高代码的性能,这样就不会出现时间复杂度问题(例如,没有嵌套for循环)。但我似乎找不到办法 任务是创建一个JavaScript选择引擎,该引擎将返回给定CSS选择器的DOM元素。我无法使用任何外部库或文档。querySelector/queryselectorAll HTML正文如下所示 <body> <div></div> <div id="some_id" class="some_c

所以我有这个问题要做练习。代码可以工作,但我希望提高代码的性能,这样就不会出现时间复杂度问题(例如,没有嵌套for循环)。但我似乎找不到办法

任务是创建一个JavaScript选择引擎,该引擎将返回给定CSS选择器的DOM元素。我无法使用任何外部库或文档。querySelector/queryselectorAll

HTML正文如下所示

 <body>
    <div></div>
    <div id="some_id" class="some_class some_other_class"></div>
    <img id="some_other_id" class="some_class some_other_class"></img>
    <input type="text">
</body>

元素具有内置的方法,允许您检查它们是否与特定选择器匹配:。对于一个已经解决的问题,不必重新发明轮子就容易多了。获取文档中的所有元素,然后在每次调用
$
时,返回这些元素的数组,并根据它们是否匹配选择器进行筛选:

const getAllChildren=(父级,结果=[])=>{
Array.prototype.forEach.call(
父母,孩子,
(儿童)=>{
结果:推(儿童);
getAllChildren(child,results);
}
);
返回结果;
};
var$=函数(选择器){
返回getAllChildren(document.body)
.filter(elm=>elm.matches(选择器));
}
console.log($(“div”)//应返回2个div
console.log($(“img.some_class”)//应返回1个img
log($(“#some_id”)//应返回1个DIV
console.log($(“.some_class”)//应该返回1个DIV和1个IMG
log($(“input#some_id”)//应该返回一个空数组
console.log($($div#some_id.some_class))//应该返回1个div
log($($div.some_class#some_id))//应返回1个div


因为他们询问了性能,所以您可能希望改用a,这仍然是遍历DOMTree(无递归)的最快方法<代码>$=(选择器)=>{const walker=document.createTreeWalker(document.body,NodeFilter.SHOW_元素,null);const nodes=[];while(walker.nextNode()){if(walker.currentNode.matches(选择器)){nodes.push(walker.currentNode)}返回节点};始终返回NodeFilter枚举(FILTER\u ACCEPT),返回布尔值将导致某些DOM结构出现问题(例如,搜索
“#引用窗格表”
将在Chrome上失败,原因我不确定……)。但是无论如何,在while循环中进行过滤,就像我在第一条注释中所做的那样,实际上(令人惊讶地)比在NodeFilter函数中进行过滤快两倍。谢谢,我看到您使用的是passing
null
,而不是完全忽略参数。它看起来像是说只有
null
的值默认为
FILTER\u ACCEPT
,但MDN说该参数是完全可选的(并且默认接受)
null
可能是安全的,我想我对旧IE有问题,并且养成了总是传递
null
的习惯。
var $ = function (selector) {

    if (typeof selector !== "string"){
        throw TypeError("Please enter a selector in a string format")
    }

    let results = [];
    let classes = getClasses();

    let hasClass, hasID, str, a

    if (document.getElementsByTagName(selector)){
        hasClass = selector.includes(".") ? true : false
        hadID = selector.includes("#") ? true : false
    }


    if (hasClass && hasID) {

        let i = 0;
        while (i < classes.length){
            if (selector.includes(classes[i])) {
                str = classes[i];
                a = document.getElementsByClassName(str);

                if (selector.includes(a[i].id)) results.push(a[i]);
            }
            i++
        }

    } else if (hasClass) {

        let list1, list2;

        for (i = 0; i < classes.length; i++) {
            if (selector.includes(classes[i])) {
                str = classes[i];
                a = document.getElementsByClassName(str);

                for (j = 0; j < a.length; j++) {
                    if (selector.charAt(0) === ".") {
                        results.push(a[j]);
                    } else if (selector.includes(a[j].tagName.toLowerCase())) {
                        results.push(a[j]);
                    }
                }
            }
        }

    } else if (hasID) {
        if (selector.charAt(0) === "#") results.push(window[selector.substring(selector.indexOf("#") + 1, selector.length)]);


    } else {
        for (var i = 0; i < t.length; i++) results.push(t[i]);
    }

    return results;
}




function getClasses(){

    let nodesArray = document.body.childNodes
    let results = [];

    i = 0;
    while (i < nodesArray.length){

        let element = nodesArray[i].nodeName;

        if (!element.includes("#")){
            for (j = 0; j < nodesArray[i].classList.length; j++) results.push(nodesArray[i].classList[j]);
        }
        i++

    }

    let x = Array.from(new Set(results))
    console.log(x)
    return x

}
$("div") - Should return 2 DIVs 
$("img.some_class") - Should return 1 IMG 
$("#some_id") - Should return 1 DIV 
$(".some_class") - Should return 1 DIV and 1 IMG 
$("input#some_id") - Should return an empty array 
$("div#some_id.some_class") - Should return 1 DIV 
$("div.some_class#some_id") - Should return 1 DIV