课前练习总结

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

<input type="text" id="ip" />

    <button id="btn">点哥</button>

    <input type="text" placeholder="请输入要查询的学生姓名" id="ip" />

    <button id="btnSet">设置成绩</button>

    <button id="btnGet">查询成绩</button>

    <p id="pInfo">成绩显示区</p>

    <h3 id="hMyname">{name}</h3>

    <p id="pMyname">{name}</p>

    <h3 id="hMyage">{age}</h3>

    <p id="pMyage">{age}</p>

    <p id="pGender">{gender}</p>

</body>

<script>

    // 1、选择排序

    const arr = [3, 4, 2, 5, 1, 6, 8, 7, 9]

    function fn() {

        let temp

        for (let p = 0; p <= arr.length - 2; p++) {

            let smallest = arr[p]

            let smallestIndex = p

            for (let i = p; i <= arr.length; i++) {

                if (arr[i] < arr[smallestIndex]) {

                    smallest = arr[i]

                    smallestIndex = i

                }

            }

            temp = arr[p]

            arr[p] = smallest

            arr[smallestIndex] = temp

        }

        console.log(arr);

    }

    //冒泡排序

    (function fn() {

        let temp

        for (let j = arr.length - 2; j >= 0; j--) {

            for (let i = 0; i <= j; i++) {

                if (arr[i] > arr[i + 1]) {

                    temp = arr[i]

                    arr[i] = arr[i + 1]

                    arr[i + 1] = temp

                }

            }

        }

        console.log(arr);

    })

    // 2、深拷贝

    (function fn(data) {

        let copy

        if (typeof (data) === 'function' || typeof (data) === 'object') {

            return data

        } else if (Array.isArray(data)) {

            copy = []

            data.forEach(function (item, index) {

                copy[index] = fn(item)

            })

            return copy

        } else {

            copy = {}

            for (let key in data) {

                copy[key] = fn(data[key])

            }

            return copy

        }

    })

    //3、手撸函数防抖与节流

    //防抖

    const inputHandler = function (e) {

        console.log(e.target);

        console.log(e.target.value);

    }

    ip.addEventListener('input', mydebounce(inputHandler, 1000))

    function mydebounce(fn, delay) {

        let timer = null

        return function (...args) {

            if (timer) {

                clearTimeout(timer)

            }

            timer = setTimeout(() => {

                fn.apply(null, args)

                timer = null

            }, delay)

        }

    }

    // 节流

    const clickHandler = function (e) {

        console.log('hello');

    }

    btn.addEventListener('click', mythrottle(clickHandler, 1000))

    function mythrottle(fn, delay) {

        let timer = null

        return function (...args) {

            if (!timer) {

                fn.apply(null, args)

                timer = setTimeout(() => {

                    timer = null

                }, delay)

            }

        }

    }

    // 4、使用连环异步回调实现求5的阶乘:

    (function fn() {

        const multiply = (a, b, callback) => {

            setTimeout(() => callback(a * b), 2000);

        };

        const mulPromise = (a, b) => {

            return new Promise(

                (resolve, reject) => {

                    multiply(a, b, (ret) => resolve(ret));

                }

            );

        };

        mulPromise(2, 3)

            .then((ret) => mulPromise(ret, 4))

            .then((ret) => mulPromise(ret, 5))

            .then((ret) => console.log("ret=", ret));

        ~(async function awaitDemo() {

            try {

                let ret = await mulPromise(2, 3);

                ret = await mulPromise(ret, 4);

                ret = await mulPromise(ret, 5);

                console.log(ret);

            } catch (err) {

                console.log("err=", err);

            }

        })();

    })

    // 5、提取URL中的查询参数

    function getSearchParams(url) {

        const obj = {};

        const reg = /\w+=\w+/g

        const arr = url.match(reg)

        arr.forEach((item) => {

            let [key, value] = item.split("=");

            obj[key] = value

        });

        return obj;

    }

    // 6、封装ajax,实现POST一个表单

    ~ function () {

        function getSearchParams(url = '') {

            const obj = {}

            url.match(/\w+=\w+/g).forEach(str => {

                let [key, value] = str.split('=')

                obj[key] = value

            })

            return obj

        }

        // obj = {

        //     name: 'heige',

        //     age: 12

        // }

        function toGetParams(obj) {

            let str = ''

            for (let key in obj) {

                str += `&${key}=${obj[key]}`

            }

            return str.slice(1)

        }

        function ajax({

            url,

            method,

            data,

            dataType,

            onSuccess,

            onFail

        }) {

            const xhr = new XMLHttpRequest()

            if (!url) {

                throw new Error('没给url')

            }

            method = method || 'GET'

            onSuccess = onSuccess || (data => console.log('default onSuccess:', data))

            onFail = onFail || (err => console.log('default onFail:', err))

            xhr.open(method, url)

            let reqBody = null

            switch (true) {

                case dataType == 'form':

                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

                    reqBody = toGetParams(data)

                    break

                case dataType == 'json':

                    xhr.setRequestHeader('Content-Type', 'application/json')

                    reqBody = JSON.stringify(data)

                    break

                default:

                    break

            }

            xhr.onload = () => onSuccess(xhr.responseText)

            xhr.onerror = err => onFail(err)

            xhr.send(reqBody)

        }

        // try {

        //   ajax({

        //     url: 'http://www.httpbin.org/post',

        //     method: 'POST',

        //     dataType: 'form',

        //     data: { name: 'admin', pwd: '123456' },

        //     onSuccess: data => console.log(data),

        //     onFail: err => console.log(err)

        //   })

        // } catch (err) {

        //   console.log('catch err:', err);

        // }

        function ajaxPromise(config) {

            return new Promise((resolve, reject) => {

                ajax({

                    ...config,

                    onSuccess: data => resolve(data),

                    onFail: err => reject(err),

                })

            })

        }

        ajaxPromise({

                url: 'http://www.httpbin.org/post',

                method: 'POST',

                dataType: 'form',

                data: {

                    name: 'admin',

                    pwd: '123456'

                },

            })

            .then(data => console.log(data))

            .catch(err => console.log(err))

    }

    // 7、带有超时功能的Promise

    function fn() {

        async function executeWithTimeout(fn, ms) {

            return new Promise(async (resolve, reject) => {

                let timer = setTimeout(() => {

                    reject("timeout");

                }, ms);

                const data = await fn();

                clearTimeout(timer);

                resolve(data);

            });

        }

        const timeout = 5000;

        function rq(url) {

            return new Promise((resolve) => {

                setTimeout(() => {

                    resolve(`来自${url}的数据`);

                }, timeout);

            });

        }

        async function fn1() {

            return rq("https://www.taobao.com");

        }

        executeWithTimeout(fn1, 3000)

            .then((value) => console.log("value=", value))

            .catch((err) => console.log("err=", err));

    }

    // 8、一次性获取多个指定页面

    function fn3() {

        async function getContentByUrl(url) {

            return new Promise((resolve, reject) =>

                setTimeout(() => {

                    Math.random() > 0.5 ? resolve(`${url}的页面内容`) : reject("timeout");

                }, 1000)

            );

        }

        const urls = [

            "https://www.taobao.com",

            "https://www.baidu.com",

            "https://web.taobao.com",

        ];

        async function fetchData(urls = []) {

            return Promise.allSettled(

                urls

                .filter((url) => url.endsWith("taobao.com"))

                .map((url) => getContentByUrl(url))

            );

        }

        fetchData(urls)

            .then((results) => console.log(results));

    }

    // 9、IP地址比大小

    function fn1() {

        function compare(ip1 = "", ip2 = "") {

            const arr1 = ip1.split(".").map((item) => item * 1);

            const arr2 = ip2.split(".").map((item) => item * 1);

            for (let i = 0; i < arr1.length; i++) {

                if (arr1[i] > arr2[i]) {

                    return 1;

                }

                if (arr1[i] < arr2[i]) {

                    return -1;

                }

            }

            return 0;

        }

        console.log(compare("1.2.3.4", "1.1.3.4"));

        console.log(compare("1.11.3.4", "1.2.3.4"));

        console.log(compare("1.2.3.4", "1.11.3.4"));

        console.log(compare("1.2.3.4", "1.2.3.4"));

    }

    // 10、实现闭包管理全班学生成绩

    function score(name) {

        const scores = {

            chinese: 0,

            math: 0,

            coding: 0,

        };

        return {

            set(key, value) {

                scores[key] = value;

            },

            getAll() {

                return `${name}:${JSON.stringify(scores)}`;

            },

        };

    }

    const arr1 = ["张三疯", "尼古拉斯赵四", "隔壁老王"]

    const obj = {}

    arr1.forEach(

        name => obj[name] = scrore(name)

    )

   btnSet.onclick = function(){

            let [name,key,value] = ip.value.split(":")

            obj[name].set(key,value)

        }

        btnGet.onclick = function(){

            const name = ip.value

            pInfo.innerText = obj[name].getAll()

        }

    // 11、手封MyMap实现一下效果

    class MyMap {

        constructor() {

            this.obj = {};

            this.size = 0;

        }

        set(key, value) {

            this.obj[key] = value;

            this.updateSize();

        }

        get(key) {

            return this.obj[key];

        }

        updateSize() {

            this.size = Object.keys(this.obj).length;

        }

        delete(key) {

            delete this.obj[key];

            this.updateSize();

        }

        clear() {

            this.obj = {};

            this.size = 0;

        }

        has(key) {

            return this.obj.hasOwnProperty(key);

        }

        forEach(handler) {

            for (let key in this.obj) {

                handler.apply(this, [this.obj[key], key, this]);

            }

        }

        keys() {

            return Object.keys(this.obj);

        }

        values() {

            return Object.keys(this.obj).map((key) => this.obj[key]);

        }

        entries() {

            return Object.keys(this.obj).map(

                (key) => ({

                    key,

                    value: this.obj[key]

                })

            );

        }

    }

    ~(function () {

        const map = new MyMap()

        map.set("name", "张三")

        map.set("age", 20)

        map.set("gender", "男")

        map.forEach(

            (value, key) => console.log(key, value)

        )

        for (let entry of map.entries()) {

            console.log(entry)

        }

        console.log(map.size)

        console.log(map.get("name"))

        console.log(map.get("age"))

        console.log(map.has("name"))

        console.log(map.has("myname"))

        map.delete("age")

        map.clear()

        console.log(map.size)

    })

    // 12、全班人马排除空座位后抽取N名幸运观众

    function fn3() {

        let stus = [];

        for (let i = 1; i < 100; i++) {

            stus.push(i);

        }

        const empties = [12, 34, 56, 78];

        stus = stus.filter((s) => empties.indexOf(s) === -1);

        const pick = (arr, n) => {

            let luckies = [];

            for (let i = 0; i < n; i++) {

                let randomIndex = parseInt(Math.random() * arr.length);

                luckies = arr.splice(randomIndex, 1).concat(luckies)

            }

            return luckies;

        };

        console.log(pick(stus, 5));

    }

    // fn3();

    // 13、手撸观察者模式:实现彩票机周期性地发布【开售】【开奖】事件,玩家开售时下注,开奖时购买,一旦中奖则彩票机停止工作;

    function observerDemo() {

        class Observable {

            constructor(name) {

                this.name = name;

                this.observers = [];

            }

            register(ob) {

                this.observers.push(ob);

                ob.observable = this;

            }

            unregister(ob) {

                this.observers = this.observers.filter((o) => o !== ob);

            }

            emit(event) {

                this.observers.forEach((ob) => ob.onEvent(event));

            }

        }

        class Observer {

            constructor(name) {

                this.name = name;

            }

            onEvent(event) {

                console.log(this.name, "响应事件", event);

            }

        }

        class Lottery extends Observable {

            constructor(name) {

                super(name);

                this.timer = null;

            }

            start() {

                if (!this.timer) {

                    this.timer = setInterval(() => {

                        const code = parseInt(Math.random() * 3);

                        console.log(this.name, "发布开奖事件", code);

                        this.emit({

                            type: "开奖",

                            code

                        });

                        this.emit({

                            type: "开售"

                        });

                    }, 2000);

                }

            }

            stop() {

                if (this.timer) {

                    clearInterval(this.timer);

                    console.log(this.name, "已停止");

                    this.timer = null;

                }

            }

        }

        class Player extends Observer {

            constructor(name) {

                super(name);

                this.code = null;

            }

            buy() {

                this.code = parseInt(Math.random() * 3);

                console.log(this.name, "下注", this.code);

            }

            check(event) {

                const isLucky = this.code === event.code;

                console.log(this.name, isLucky ? "中奖了" : "未中奖");

                isLucky && this.observable.stop();

            }

            onEvent(event) {

                super.onEvent(event);

                switch (event.type) {

                    case "开售":

                        this.buy();

                        break;

                    case "开奖":

                        this.check(event);

                        break;

                    default:

                        break;

                }

                console.log("");

            }

        }

        ~(function main() {

            const lot = new Lottery("六合彩");

            const tiger = new Player("打老虎");

            const gaojin = new Player("高进");

            lot.register(tiger);

            lot.register(gaojin);

            lot.unregister(gaojin);

            lot.start();

        })();

    }

    // observerDemo();

    // 14、实现任意多个入参的函数fn的柯里化

    function curryDemo() {

        const curry = (fn) => {

            return function cfn(...args) {

                if (args.length === fn.length) {

                    return fn.apply(null, args);

                }

                return function (...b) {

                    args = args.concat(b);

                    return cfn(...args);

                };

            };

        };

        const cadd = curry(add);

        console.log(cadd(1, 2, 3, 4));

        console.log(cadd(1, 2)(3)(4));

    }

    // curryDemo();

    // 15、实现任意多个函数的管道与组合

    function pipeDemo() {

        const pipe = (...fns) => (v => fns.reduce(

            (pv, fn, index) => fn(pv),

            v

        ))

        const compose = (...fns) => (v => fns.reverse().reduce(

            (pv, fn, index) => fn(pv),

            v

        ))

        const len = (n) => (n + "").length;

        const pow = (n) => n * n;

        const cubicRoot = (n) => Math.cbrt(n);

        console.log(compose(len, pow, cubicRoot)(1000));

    }

    // pipeDemo();

    // 16、函数的Promise化

    async function promDemo() {

        function promisify(fn) {

            return function (...args) {

                return new Promise(

                    (resolve, reject) => {

                        try {

                            resolve(fn.apply(null, args))

                        } catch (err) {

                            reject(err)

                        }

                    }

                )

            }

        }

        const add = (a, b, c, d) => {

            if (Math.random() > 0.7) {

                throw new Error("人品槽已空,请尽快充100块钱的人品")

            }

            return a + b + c + d

        }

        const pow = (a, b) => {

            if (Math.random() > 0.7) {

                throw new Error("人品槽已空,请尽快充100块钱的人品")

            }

            return Math.pow(a, b)

        }

        const padd = promisify(add)

        const ppow = promisify(pow)

        // padd(1,2,3,4).then(

        //     data => {

        //         console.log("data=",data)

        //         return ppow(data,2)

        //     }

        // )

        // .then(

        //     data => console.log("data=",data)

        // )

        // .catch(

        //     err => console.error("err=",err)

        // )

        try {

            let data = await padd(1, 2, 3, 4)

            console.log("data=", data)

            data = await ppow(data, 2)

            console.log("data=", data)

        } catch (err) {

            console.error("err=", err)

        }

    }

    // promDemo()

    // 17、封装MongoDB数据引擎层

    async function fn3() {

        function getCollection(dbName, collectionName) {

            return new Promise(

                (resolve, reject) => {

                    var MongoClient = require("mongodb").MongoClient;

                    var url = "mongodb://localhost:27017/";

                    MongoClient.connect(url, function (err, conn) {

                        if (err) {

                            resolve({

                                err,

                                collection: undefined,

                                conn: undefined,

                            });

                            return;

                        }

                        var dbo = conn.db(dbName);

                        const collection = dbo.collection(collectionName);

                        resolve({

                            err: undefined,

                            collection,

                            conn,

                        });

                    });

                }

            );

        }

        async function doCreate(dbName, collectionName, dataObj) {

            const {

                err,

                collection,

                conn

            } = await getCollection(

                dbName,

                collectionName

            );

            if (err) {

                return {

                    err,

                    res: undefined,

                };

            }

            collection.insertOne(dataObj, function (err, res) {

                conn.close();

                return {

                    err,

                    res,

                };

            });

        }

        async function addUser(user) {

            const ret = await doCreate(dbName, collectionName, user);

            return ret;

        }

    }

    // fn3();

    //18、异步函数的Promise化

    function fn2() {

        function add(a, b) {

            return a + b;

        }

        function multiply(a, b, callback) {

            setTimeout(() => callback(a * b), 1000);

        }

        function promisify(fn) {

            return function pfn(...args) {

                return new Promise(

                    (resolve, reject) => {

                        const ret = fn.apply(null, [...args, (...a) => resolve(a)]);

                        ret && resolve(ret);

                    }

                );

            };

        }

        /* 同步返回函数的Promise化 */

        //   const padd = promisify(add);

        //   padd(2, 3).then(

        //     (value) => console.log("value=", value) //5

        //   );

        const pmul = promisify(multiply);

        pmul(2, 3)

            .then((values) => {

                console.log("value=", values);

                return pmul(values[0], 4);

            })

            .then((values) => {

                console.log("value=", values);

                return pmul(values[0], 5);

            })

            .then((values) => console.log(values[0]));

    }

    // fn2();

    //19、 手撸数据驱动视图微框架

    function defineReactive(data, keys = []) {

        keys.forEach(

            ({

                name,

                listeners

            }) => {

                Object.defineProperty(data, name, {

                    get() {

                        console.log("get", name);

                        return data[`x_${name}`];

                    },

                    set(newValue) {

                        console.log("set", name, newValue);

                        data[`x_${name}`] = newValue;

                        listeners.forEach((dom) => (dom.innerText = newValue));

                    },

                });

            }

        );

    }

    const data = {};

    defineReactive(data, [{

            name: "age",

            listeners: [hMyage, pMyage]

        },

        {

            name: "name",

            listeners: [hMyname, pMyname]

        },

        {

            name: "gender",

            listeners: [pGender]

        },

    ]);

    data.name = "黑哥";

    data.age = 18;

    data.gender = "男";

    setInterval(() => {

        data.name = Date.now();

        data.age = data.age + 1;

        data.gender = data.gender === "男" ? "女" : "男";

    }, 1000);

    //20、数组APIreduce

    const arr12=[1,2,3,4]

    const initialValue=0

    const sunWithInitial=arr12.reduce((previousValue,currentValue)=>previousValue+currentValue,initialValue)

    console.log(sunWithInitial);

</script>

</html>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容