欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

javascript中Proxy的應(yīng)用場景-創(chuàng)新互聯(lián)

前言

隨著 vue3.x 的消息越來越多,proxy 的討論也。相對于 Object.definePropertyproxy 有什么區(qū)別,有什么優(yōu)勢,以及可以應(yīng)用在什么地方。該文章就簡單的介紹下

創(chuàng)新互聯(lián)公司長期為千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為新吳企業(yè)提供專業(yè)的成都做網(wǎng)站、網(wǎng)站設(shè)計、外貿(mào)營銷網(wǎng)站建設(shè)新吳網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。Object.defineProperty

proxy 之前,先回顧下 Object.defineProperty 。大家都知道,vue2.x 以及之前的版本是使用 Object.defineProperty 實現(xiàn)數(shù)據(jù)的雙向綁定的,至于是怎樣綁定的呢?下面簡單實現(xiàn)一下

function observer(obj) {
    if (typeof obj === 'object') {
        for (let key in obj) {
            defineReactive(obj, key, obj[key])
        }
    }
}
function defineReactive(obj, key, value) { //針對value是對象,遞歸檢測
    observer(value) //劫持對象的key
    Object.defineProperty(obj, key, {
        get() {
            console.log('獲取:' + key) return value
        },
        set(val) { //針對所設(shè)置的val是對象
            observer(val) console.log(key + "-數(shù)據(jù)改變了") value = val
        }
    })
}
let obj = {
    name: '守候',
    flag: {
        book: {
            name: 'js',
            page: 325
        },
        interest: ['火鍋', '旅游'],
    }
}

observer(obj)

在瀏覽器的 console 執(zhí)行一下,似乎能正常運行

但是實際上,Object.defineProperty 問題有以下幾個

問題1.刪除或者增加對象屬性無法監(jiān)聽到

比如增加一個屬性 gender ,由于在執(zhí)行 observer(obj) 的時候,沒有這個屬性,所以這個無法監(jiān)聽到。刪除的屬性也是無法監(jiān)聽到

增加屬性的時候, vue 需要使用 $set 進行操作,$set 的內(nèi)部也是使用 Object.defineProperty 進行操作

問題2.數(shù)組的變化無法監(jiān)聽到

由上圖得知,雖然數(shù)組屬性實際上是修改成功了,但是不能被監(jiān)聽到

問題3. 由于是使用遞歸遍歷對象,使用 Object.defineProperty  劫持對象的屬性,如果遍歷的對象層級比較深,花的時間比較久,甚至有性能的問題

proxy

對于 proxy ,在 mdn 上的描述是: 對象用于定義基本操作的自定義行為(如屬性查找、賦值、枚舉、函數(shù)調(diào)用等)

簡單來說就是,可以在對目標(biāo)對象設(shè)置一層攔截。無論對目標(biāo)對象進行什么操作,都要經(jīng)過這層攔截

聽上去似乎,proxyObject.defineProperty 要好用,并且簡單很多,實際上就是如此。下面用 proxy 對上面的代碼進行改寫試下

function observerProxy(obj) {
    let handler = {
        get(target, key, receiver) {
            console.log('獲取:' + key) // 如果是對象,就遞歸添加 proxy 攔截
            if (typeof target[key] === 'object' && target[key] !== null) {
                return new Proxy(target[key], handler)
            }
            return Reflect.get(target, key, receiver)
        },
        set(target, key, value, receiver) {
            console.log(key + "-數(shù)據(jù)改變了") return Reflect.set(target, key, value, receiver)
        }
    }
    return new Proxy(obj, handler)
}
let obj = {
    name: '守候',
    flag: {
        book: {
            name: 'js',
            page: 325
        },
        interest: ['火鍋', '旅游'],
    }
}
let objTest = observerProxy(obj)

也是一樣的效果

而且,能做到 Object.defineProperty 做不到的事情,比如增加一個屬性 gender,能夠監(jiān)聽到

操作數(shù)組,也能監(jiān)聽到

最后敲一下黑板,簡單總結(jié)一下兩者的區(qū)別

1.Object.defineProperty 攔截的是對象的屬性,會改變原對象。proxy 是攔截整個對象,通過 new 生成一個新對象,不會改變原對象。

2.proxy 的攔截方式,除了上面的 get 和 set ,還有 11 種。選擇的方式很多 Proxy,也可以監(jiān)聽一些  Object.defineProperty 監(jiān)聽不到的操作,比如監(jiān)聽數(shù)組,監(jiān)聽對象屬性的新增,刪除等。

proxy 使用場景

關(guān)于 proxy 的使用場景,受限于篇幅,這里就簡單列舉幾個,更多的可以移步我的 github 筆記或者 mdn。

看到這里,兩者的區(qū)別,和 proxy 的優(yōu)勢已經(jīng)知道個大概了。但是在開發(fā)上,有哪些場景可以使用到 proxy 呢,下面列舉個可能會遇上的情況

負(fù)索引數(shù)組

在使用 splice(-1)slice(-1) 等 API 的時候,當(dāng)輸入負(fù)數(shù)的時候,會定位到數(shù)組的最后一項,但是在普通數(shù)組上,并不能使用負(fù)數(shù)。 [1,2,3][-1] 這個代碼并不能輸出 3 。要讓上面的代碼輸出 3 , 也可以使用 proxy 實現(xiàn)。


表單校驗

在對表單的值進行改動的時候,可以在 set 里面進行攔截,判斷值是否合法

let ecValidate = {
    set(target, key, value, receiver) {
        if (key === 'age') { //如果值小于0,或者不是正整數(shù)
            if (value < 0 || !Number.isInteger(value)) {
                throw new TypeError('請輸入正確的年齡');
            }
        }
        return Reflect.set(target, key, value, receiver)
    }
}
let obj = new Proxy({
    age: 18
},
ecValidate) obj.age = 16obj.age = '少年'

增加附加屬性

比如有一個需求,保證用戶輸入正確身份證號碼之后,把出生年月,籍貫,性別都添加進用戶信息里面

眾所周知,身份證號碼第一和第二位代表所在省(自治區(qū),直轄市,特別行政區(qū)),第三和第四位代表所在市(地級市、自治州、盟及國家直轄市所屬市轄區(qū)和縣的匯總碼)。第七至第十四位是出生年月日。低17位代表性別,男單女雙。

const PROVINCE_NUMBER = {
    44 : '廣東省',
    46 : '海南省'
}
const CITY_NUMBER = {
    4401 : '廣州市',
    4601 : '海口市'
}
let ecCardNumber = {
    set(target, key, value, receiver) {
        if (key === 'cardNumber') {
            Reflect.set(target, 'hometown', PROVINCE_NUMBER[value.substr(0, 2)] + CITY_NUMBER[value.substr(0, 4)], receiver) Reflect.set(target, 'date', value.substr(6, 8), receiver) Reflect.set(target, 'gender', value.substr( - 2, 1) % 2 === 1 ? '男': '女', receiver)
        }
        return Reflect.set(target, key, value, receiver)
    }
}
let obj = new Proxy({
    cardNumber: ''
},
ecCardNumber)

數(shù)據(jù)格式化

比如有一個需求,需要傳時間戳給到后端,但是前端拿到的是一個時間字符串,這個也可以用 proxy 進行攔截,當(dāng)?shù)玫綍r間字符串之后,可以自動加上時間戳。

let ecArrayProxy = {
    get(target, key, receiver) {
        let _index = key < 0 ? target.length + Number(key) : key
        return Reflect.get(target, _index, receiver)
    }
}
let arr = new Proxy([1, 2, 3], ecArrayProxy)

以上就是JS Proxy 的優(yōu)勢以及使用場景的詳細內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!

當(dāng)前題目:javascript中Proxy的應(yīng)用場景-創(chuàng)新互聯(lián)
鏈接分享:http://www.chinadenli.net/article2/dcdjic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站商城網(wǎng)站電子商務(wù)服務(wù)器托管網(wǎng)站導(dǎo)航搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化