关于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)
相关推荐
史努比的大头2 分钟前
前端开发深入了解性能优化
前端
码农研究僧4 分钟前
Java或者前端 实现中文排序(调API的Demo)
java·前端·localecompare·中文排序·collator
营赢盈英10 分钟前
OpenAI API key not working in my React App
javascript·ai·openai·reactjs·chatbot
吕永强42 分钟前
HTML表单标签
前端·html·表单标签
范特西是只猫1 小时前
echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】
前端·javascript·echarts
麒麟而非淇淋1 小时前
AJAX 进阶 day4
前端·javascript·ajax
图灵苹果1 小时前
【个人博客hexo版】hexo安装时会出现的一些问题
前端·前端框架·npm·node.js
IT-陈2 小时前
app抓包 chrome://inspect/#devices
前端·chrome
hahaha 1hhh5 小时前
Long类型前后端数据不一致
前端