小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
对象是我们编程中最常的数据类型,也是最重要的数据类型,一起来了解他吧。
属性的来源
静态属性
比如Object.assign, Array.from这类,就属于静态属性,直接调用即可。
实例属性
需要被实例化,之后可以调用的方法,主要又为两类:
- 函数作为构造函数的实例
function Person(name, age){
this.name = name;
this.age = age;
this.getName = function(){
return name
}
}
Person.prototype.getAge = function(){
return this.age;
}
var person = new Person()
name 和 getName都是直属于person上,而不是其原型上。
- class实例
class Person {
constructor(name, age){
this.name = name
this.age = age
}
getName = ()=> {
return this.name
}
getAge(){
return this.age
}
}
getName就是实例属性
原型属性
同上面的代码, getAge就是原型上属性
Person.prototype.getAge = function(){
return this.age;
}
下面的getAge就是原型上属性
class Person {
constructor(name, age){
this.name = name
this.age = age
}
getName = ()=> {
return this.name
}
getAge(){
return this.age
}
}
属性的可访问性
可以通过Object.defineProperty或者Object.defineProperties进行设置,设置的可选项如下:
- configurable —— 如果设为true,则可以修改或删除属性。如果设为false,则不允许修改。
- enumerable —— 如果设为true,则可在for-in循环对象属性时出现(我们很快会介绍for-in循环)。
- value —— 指定属性的值,默认为undefined。
- writable —— 如果设为true,则可通过赋值语句修改属性值。
- get —— 定义getter函数,当访问属性时发生调用,不能与value与writable同时使用。
- set —— 定义setter函数,当对属性赋值时发生调用,也不能与value与writable同时使用。
颇有一些AOP,原子编程的思想。 后来ES5加入了Extension,freeze, seal等快捷操作,均可以对等到这上面的操作来。
vue3前期监听数据变化的核心,也就是这个Object.defineProperty, 当然,平时我们用到不多,因为主要写业务。
如果是写工具库,那就尤其重要了。
比如做一个简单的数据验证:
var product = {
price: 10
}
Object.defineProperty(product, 'price', {
set(val){
if(val<0){
throw new Error("price 必须大于0");
}
}
})
product.price = -10
当然,ES6时代的到来,现在都流行Proxy来控制对象的访问了,目前Object.defineProperty系列的优势,可能就是兼容性吧,随着ES6逐渐普及,可能作用越来越小。
个人觉得,其还有一个优势,就是不想Proxy那样,返回的是一个新的对象,您说对吧。
小结
今天你收获了吗?