关于Harmony的学习

day29

一、函数柯里化

又译为卡瑞化或加里化 是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数 并且返回接受余下的参数而且返回结果的新函数的技术 作用: 可以固定相同参数,实现函数调用传参的简单化 可以让参数复用

1.输出一个完整的url地址:一定要把不变的参数放在第一位

复制代码
    function printUrl(protocol){
        return function(domain){
            return function(port){
                return protocol + domain + port
            }
        }
    }
    let result = printUrl('https://')
    let url1 = result('www.baidu.com')(':8080')
    let url2 = result('www.jd.com')(':6666')
    console.log(url1)
    console.log(url2)

2.假设你是一个商家,要出售商品,为了卖出去更多的商品,今天决定打9折进行售卖,我们可以使用以下函数进行折扣后的售出价格计算

复制代码
    function discPrice(disc){
        return function(price){
            return price * disc
        }
    }
    let result = discPrice(.8)
    let price1 = result(1000)
    let price2 = result(2000)
    console.log(price1)
    console.log(price2)

二、原型继承

继承是把一个构造函数的属性和方法继承到另一个构造函数里面,而继承必须是同类之间的继承。

原型继承:利用了原型链的规则来实现继承

复制代码
    // 父类构造函数
    function Father(name, age){
        this.name = name
        this.age = age
    }
    Father.prototype.money = function(){
        console.log('一个小目标')
    }
​
    // 子类构造函数
    function Son(name, age){
        this.name = name
        this.age = age
    }
​
    Son.prototype = Father.prototype
    Son.prototype.love = function(){
        console.log('谈恋爱')
    }
​
    let s1 = new Son('张三', 18)
​
    s1.money()
    s1.love()
​
    let f1 = new Father('张', 36)
    f1.money()
    f1.love()
​
    console.log(Father.prototype, Son.prototype)
复制代码
    // 父类构造函数
    function Father(name, age){
        this.name = name
        this.age = age
    }
    Father.prototype.money = function(){
        console.log('一个小目标')
    }
​
    // 子类构造函数
    function Son(name, age){
        // this.name = name
        // this.age = age
    }
​
    // 把父元素的实例化对象赋值给子类的原型对象了
    Son.prototype = new Father('张三', 18)
    Son.prototype.love = function(){
        console.log('谈恋爱')
    }
​
    let s1 = new Son()
​
    s1.money()
    s1.love()
​
    console.log(s1.name, s1.age)

三、继承

1.借用构造函数继承

复制代码
    // 父类构造函数
    function Father(name, age){
        this.name = name
        this.age = age
        this.say = function(){
            console.log('hello')
        }
​
        console.log('-------',  this)
    }
    Father.prototype.money = function(){
        console.log('一个小目标')
    }
​
    // 子类构造函数
    function Son(name, age){
        // 借用构造函数继承
        Father.call(this, name, age)
    }
​
    let s = new Son('张三', 18)
    console.log(s)

2.组合继承

复制代码
    // 父类构造函数
    function Father(name, age){
        this.name = name
        this.age = age
        this.say = function(){
            console.log('hello')
        }
    }
    Father.prototype.money = function(){
        console.log('一个小目标')
    }
​
    // 子类构造函数
    function Son(name, age){
        // 借用构造函数继承
        Father.call(this, name, age)
    }
    Son.prototype = new Father()
​
    let s = new Son('张三', 18)
    console.log(s)
​
    s.money()

3.ES6继承

复制代码
    // ES6继承原理还是组合继承
    class Father {
        constructor(name, age){
            this.name = name
            this.age = age
        }
        money(){
            console.log('一个小目标')
        }
    }
    
    class Son extends Father {
        constructor(name, age, sex){
            // super(name, age) 其实就是借用构造函数继承
            super(name, age, sex)
            this.sex = sex
            this.init()
        }
        init(){
            console.log('初始化方法')
        }
    }
​
    let s = new Son('张三', 18, '男')
    console.log(s)
​
    s.money()
​
    console.log(Son.prototype)

四、拷贝

1.浅拷贝 对象的复制只是复制对象的引用,可以改变原始数据的值。 基本数据类型拷贝过去是直接拷贝,而引用数据类型拷贝则拷贝的是地址

复制代码
    let obj = {
        name: '张三',
        age: 18,
        like: ['篮球', 'rap', '剧本杀']
    }
    let obj2 = {}
    for(let key in obj){
        obj2[key] = obj[key]
    }
    obj2.like[0] = '唱歌'
    obj2.name = '张'
    console.log(obj, obj2)

2.深拷贝(直接修改可能会造成隐性问题,深拷贝能帮你更安全安心的去操作数据,根据实际情况来使用深拷贝) 彻底复制一个对象,而不是简单的拷贝对象的引用,拷贝后不能修改原始数据的值 只有基本数据类型可以完全拷贝,拷贝的不是地址。因此利于这个规则实现深拷贝

复制代码
    let obj = {
        name: '张三',
        age: 18,
        like: ['篮球', 'rap', '剧本杀']
    }
    let obj2 = JSON.parse(JSON.stringify(obj))
    obj2.like[0] = '🎤'
    console.log(obj, obj2)

五、数据劫持(对对象的限定)

1.Object.defineProperty()

参数:=> 参数1表示那个对象需要劫持

=> 参数2表示的是设置那个属性

=> 参数3表示的是对这个属性的限定(配置项,类型是一个对象)

复制代码
       let obj = {
          name: '张',
          age: 18,
          sex: '男'
       }
   console.log(obj.name)
   for(let key in obj){
       console.log(obj[key])
   }
   delete obj.name
   console.log(obj)

注意点:被劫持的对象,通过劫持的方式设置的属性和值,为了做区分,当咱们打印查看结果时,劫持设置的值你是看不到,会默认放在一个括号里面

2.配置项:=> value: 该属性对应的值, ​ => configurable 该属性是否能被删除 ​ => writable: 该属性时候可被重写, 默认是 false ​ => emunerable: 该属性是否可被枚举(遍历), 默认是 false ​ => get: 是一个函数, 叫做 getter 获取器, 可以来决定该属性的值 ​ -> get 函数的返回值, 就是当前这个属性的值 ​ -> 注意: 不能和 value 和 writable 一起使用, 会报错 ​ => set: 是一个函数, 叫做 setter 设置器, 当你需要修改该属性的值的时候, 会触发该函数

复制代码
   let obj = {
        age: 18,
        sex: '男'
    }
    Object.defineProperty(obj, 'name', {
        value: '陈',
        configurable: false,
        writable: false,
        enumerable: false
    })
    // delete obj.name
    // obj.name = '张'
    for(let key in obj){
        console.log(obj[key])
    }
    // console.log(obj)

3.get和set:

复制代码
    let obj = {
        age: 18,
        sex: '男'
    }
    let _name = 'hello'
    Object.defineProperty(obj, 'name', {
        // 获取器,肯定是先有值,才能获取
        get(){
            console.log('我的属性被获取了')
            return _name
        },
        set(value){
            console.log('我的属性被修改了')
            _name = value
        }
    })
    console.log(obj.name)
    obj.name = ''
    console.log(obj.name)
复制代码
    // 目标对象,要被劫持的目标对象
    let target = {}

    // 专门用来设置属性的对象,它的作用和刚才那个_name全局变量的作用是一样的
    let setObj = {
        name: '陶',
        age: 18
    }
    Object.defineProperty(target, 'name', {
        get(){
            console.log('我的属性被获取了')
            return setObj.name
        },
        set(value){
            console.log('我的属性被修改了')
            setObj.name = value
        }
    })
    Object.defineProperty(target, 'age', {
        get(){
            console.log('我的属性被获取了')
            return setObj.age
        },
        set(value){
            console.log('我的属性被修改了')
            setObj.age = value
        }
    })
    console.log(target.name)
    target.name = '张'
    console.log(target.name)

    console.log(target)

5.封装

复制代码
    let setObj = {
        name: '',
        age: 18,
        sex: '男'
    }

    // 参数1表示给目标对象设置值的对象
    // 参数2表示回调函数
    function reactive(setObj, callback){
        let target = {}
        for(let key in setObj){
            Object.defineProperty(target, key, {
                get(){
                    return setObj[key]
                },
                set(value){
                    setObj[key] = value
                    // if(callback){
                    //     callback(target)
                    // }
                    // 优雅的写法,利于短路运算符
                    callback && callback(target)
                }
            })
        }
        return target
    }
    let result = reactive(setObj, render)
    
    function render(result){
        document.querySelector('h1').innerHTML = `大家好,我就是曾经江湖中的传说,${result.name}, 他的年龄是:${result.age},他的性别是:${result.sex} `
    }
    render(result)

6.数据劫持升级

复制代码
    let setObj = {
        name: '张',
        age: 18
    }
    // Object.defineProperty()
    let target = {}
    Object.defineProperties(target, {
        'name': {
            get(){
                return setObj.name
            },
            set(value){
                setObj.name = value
            }
        },
        'age': {
            get(){
                return setObj.age
            },
            set(value){
                setObj.age = value
            }
        }
    })
    console.log(target)

7.ES6_Proxy

复制代码
    let setObj = {
        name: '张三',
        age: 18,
        sex: '女'
    }
    function reactive(data, callback){
        return new Proxy(data, {
            get(target, property){
                return target[property]
            },
            set(target, property, value){
                target[property] = value
                callback && callback(target)
            }
        })
    }
    let result = reactive(setObj, render)
    function render(result){
        document.querySelector('h1').innerHTML = `大家好,我就是曾经江湖中的传说,${result.name}, 他的年龄是:${result.age},他的性别是:${result.sex} `
    }
    render(result)

    console.log(result)

六、响应式数据(数据改变,界面跟着变)

复制代码
    let setObj = {
        name: '张',
        age: 18
    }
    let target = {}
    Object.defineProperty(target, 'name', {
        get(){
            return setObj.name
        },
        set(value){
            setObj.name = value
            render(target)
        }
    })
​
    Object.defineProperty(target, 'age', {
        get(){
            return setObj.age
        },
        set(value){
            setObj.age = value
            render(target)
        }
    })
    
    function render(target){
        document.querySelector('h1').innerHTML = `大家好,我就是曾经江湖中的传说,${target.name}, 他的年龄是:${target.age} `
    }
    render(target)
相关推荐
hackeroink1 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者3 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-3 小时前
验证码机制
前端·后端
燃先生._.4 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
南宫生5 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
高山我梦口香糖5 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
sanguine__5 小时前
Web APIs学习 (操作DOM BOM)
学习
m0_748235245 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240256 小时前
前端如何检测用户登录状态是否过期
前端