# 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
}
}
# 属性描述符中的get和set
在属性描述符中,可以使用get和set来获取和设置属性的值
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'
# call、apply和bind方法
# 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)('肉', '骨头')//我是 小花猫 我喜欢吃肉和骨头
浏览器渲染原理 →