欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

在javascript对象内搜索,貌似是一个新鲜的话题。

程序员文章站 2022-05-15 15:13:26
为啥 也不为啥,因为没找到。 用途 也没啥用途,比如,在电影网站找到链接,在小说网站找到链接。二货同事写的复杂对象。等等吧。反正要搜索就对了。 目标 在对象内,无论多少层,找到关键字。 关键字可能的位置 1.属性名,2.属性值,3.方法名,4.方法内。 一个简单的办法 把对象转成json,搜索字符串 ......

 为啥

  也不为啥,因为没找到。

用途

  也没啥用途,比如,在电影网站找到链接,在小说网站找到链接。二货同事写的复杂对象。等等吧。反正要搜索就对了。

目标

  在对象内,无论多少层,找到关键字。

关键字可能的位置

  1.属性名,2.属性值,3.方法名,4.方法内。

一个简单的办法

  把对象转成json,搜索字符串,对于不需要处理方法的前提下,非常方便,甚至可以用正则表达式去处理,然而,搜索到的结果只是定位,要还原出路径就难了。

另一个简单的办法

  遍历对象,很直接,一个递归搜到底,就一个坑,循环嵌套对象要怎么处理。

爬坑

  给每个见过的对象做一个标记,见到标记就不再看内部了。要是标记的对象里包含目标字符串,可以保存一个对象路径,要是只关心值,就可以不保存了。

聊着聊着,问题就分析明白了。做一个非常唯一的标记很重要,还要记得删除这个标记,好反复搜索。

var findinobject = {
    fio_marked: 1,
    customobjects: [],
    marked: [],
    searchresult: [],
    defaultname: ['frames', 'self', 'window', 'parent', 'top', 'location', 'content', 'document', 'history', 'locationbar', 'menubar', 'personalbar', 'scrollbars', 'statusbar', 'toolbar', 'navigator', 'applicationcache', 'customelements', 'screen', 'clientinformation', 'stylemedia', 'performance', 'caches', 'crypto', 'indexeddb', 'webkitstorageinfo', 'sessionstorage', 'localstorage', 'visualviewport', 'speechsynthesis', 'chrome', 'external', 'qb_external', 'qb_minivideo', 'qbmv', 'userobjects', 'defaultstatus', 'll', 'lll', 'gnp', 'vm'],
    fio(obj, str, path, flag) {

        if (!path) path = 'window'
        if (!flag) flag = 'fioflg_' + date.parse(new date())
        const otype = typeof obj
        if (otype == 'string') {
            if (obj.indexof(str) > -1) {
                this.searchresult.push({ path: path, type: "值命中", value: obj })
            }
        } else if (typeof obj == 'function') {
            var strfunc = obj.tostring()
            if (strfunc.indexof(str) > -1) {
                this.searchresult.push({ path: path, type: '方法内命中', value: strfunc })
            }
        } else if (typeof obj == 'number') {} else if (typeof obj == 'bigint') {} else if (typeof obj == 'boolean') {} else if (typeof obj == 'symbol') {} else if (array.isarray(obj)) {
            if (this.ismarked(obj, flag) == false) {
                for (const key in obj) {
                    if (obj.hasownproperty(key)) {
                        const element = obj[key];
                        this.fio(element, str, path + '[' + key + ']', flag)
                    }
                }
            }
        } else if (obj instanceof object) {
            if (this.ismarked(obj, flag) == false) {
                if (obj[str] != undefined) {
                    this.searchresult.push({ path: path + '/' + str, type: '属性命中', value: obj[str] })
                }
                for (const key in obj) {
                    if (this.defaultname.indexof(key) == -1) {
                        if (obj.hasownproperty(key)) {
                            try {
                                var element = obj[key]
                            } catch (error) {
                                var element = {}
                            }

                            if (path == 'window') {
                                var ty = typeof element
                                if (['function', 'number', 'bigint', 'boolean', 'symbol', 'string'].indexof(ty) == -1 && array.isarray(element) == false && element instanceof object) {
                                    this['customobjects'][key] = element
                                }
                            }
                            this.fio(element, str, path + '.' + key, flag)
                        }
                    }
                }
            }
        }
    },
    ismarked(obj, flag) {
        if (obj.fio_marked) {
            return true
        } else {
            obj.fio_marked = flag
            this.marked.push(obj)
            return false
        }
    },
    search(str) {
        this.fio(window, str)
        this.marked.foreach(item => {
            delete item['fio_marked']
        });
        this.marked = []
        console.log(this)
    },
}

没处理命中标记,其他的还都ok