# Javascript

# 事件修饰符

在构造函数中,new出来的数据容易被外部修改,所以需要使用事件修饰符来修饰数据

const goods = {
    price: 100,
    title: 'iphone',
    desc: 'good phone',
    pic: 'https://www.baidu.com/img/bd_logo1.png',
}

class UiGoods {
    constructor(goods) {
        this.data = goods
        this.choose = 0
    }
}

const ui = new UiGoods(goods)
ui.data = null
console.log('商品:', ui)//{data:null,choose:0}

# 获取对象的属性描述符

使用object.getOwnPropertyDescriptors(对象,对象中的属性)可获取对象属性的属性描述符 属性描述符具有四个值

  • configurable:属性描述符是否可以被修改
  • enumerable:是否可以被枚举/遍历
  • writable:是否可以被修改
  • value:属性的值
console.log('事件修饰符', Object.getOwnPropertyDescriptor(ui, 'data'))//{value: null, writable: true, enumerable: true, configurable: true}

# 重新定义某个属性的描述符

使用Object.defineProperty(对象,属性,属性描述符:{})可以重新定义某个属性的描述符

const ui = new UiGoods(goods)
Object.defineProperty(ui, 'data', {
    value: '123',
    writable: false,//不可重写
    configurable: false,//属性描述符不能被修改
    enumerable: false//不可枚举
})
console.log('商品:', ui)//{choose: 0, data: "123"}
console.log('属性', Object.keys(ui))//["choose"]
console.log('属性值', Object.values(ui))//[0]
Object.defineProperty(ui, 'data', {
    writable: true,//可重写
})
ui.data = '456'
console.log('商品:', ui)//{choose: 0, data: "123"}

# 使用属性描述符限制行为

class UiGoods {
    constructor(goods) {
        Object.defineProperty(this, 'data', {
            value: goods,
            writable: false,
            configurable: false,
        })
        this.choose = 0
    }
}

# 属性描述符中的getset

在属性描述符中,可以使用getset来获取和设置属性的值

const goods = {
    price: 100,
    title: 'iphone',
    desc: 'good phone',
    pic: 'https://www.baidu.com/img/bd_logo1.png',
}

class UiGoods {

    constructor(goods) {
        Object.defineProperty(this, 'data', {
            get() {
                return goods
            },
            set(value) {
                throw new Error('data不允许修改')
            }
        })
        this.choose = 0
    }
}

const ui = new UiGoods(goods)
console.log('ui', ui.data)
ui.data = '123'

# callapplybind方法

# call方法

  • call方法是一个方法,是一个函数的方法
  • call方法可以调用函数
  • call方法可以改变函数的上下文也就是this指向
  • call方法第一个参数是函数的上下文,第二个往后的参数都是传递给函数的参数
const fun = function () {
    console.log('this', this.name)
    console.log('hello')
}
//`call`方法可以调用函数
//在js中this指向全局globel
fun.call()//undefined
const people = {
    name: '张三',
    age: 18,
    sayHello: function () {
        console.log(`hello, my name is ${this.name}`)
    }
}
//`call`方法可以改变函数的上下文也就是`this`指向
fun.call(people)//张三

const lisi = {
    name: '李四',
}
fun.call(lisi)//李四

# apply方法

  • apply方法与call方法类似,不同的是apply方法接收两个参数,第一个参数是函数的上下文,第二个参数是传递给函数的参数
  • apply方法的第二个参数是个数组
const dog = {
    name: '小狗',
    sayHello() {
        console.log('我是', this.name)
    },
    hobby(food1, food2) {
        console.log('我是', this.name)
        console.log(`我喜欢吃${food1}${food2}`)
    }
}
cat.sayHello()//我是 小花猫
//改变函数的this指向
cat.sayHello.call(dog)//我是 小狗

dog.hobby.call(cat, '肉', '骨头')//我是 小花猫 我喜欢吃肉和骨头
dog.hobby.apply(cat, ['肉', '骨头'])//我是 小花猫 我喜欢吃肉和骨头

# bind方法

  • bind方法与call方法类似,不同的是bind方法返回一个新的函数
  • bind方法第一个参数是函数的上下文,第二个往后的参数都是传递给函数的参数
const dog = {
    name: '小狗',
    sayHello() {
        console.log('我是', this.name)
    },
    hobby(food1, food2) {
        console.log('我是', this.name)
        console.log(`我喜欢吃${food1}${food2}`)
    }
}
//bind方法使用方式跟call函数相同
//bind方法不会调用函数 而是把把绑定好this并传完参数的函数作为返回值给返回出来
dog.hobby.bind(cat)//无输出
const fun1 = dog.hobby.bind(cat, '肉', '骨头')
//调用bind方法返回的函数
fun1()//我是 小花猫 我喜欢吃肉和骨头
//调用方法二
dog.hobby.bind(cat)('肉', '骨头')//我是 小花猫 我喜欢吃肉和骨头
上次更新: 1/3/2024, 8:33:47 PM