对象
1. 创建对象的 5 种方式
-
字面量表示法创建
var Person = { name: "Jason", age: 21, }; -
较高 ES 版本支持变量键,即
var Name = "name" + "_example"; var Person = { [Name]: "Jason", age: 21, }; -
内置构造函数创建
var Person = new Object(); Person.name = "Jason";- 也可以通过中括号赋值,因此也支持变量键
Person["name"] = "Jason";
- 也可以通过中括号赋值,因此也支持变量键
-
工厂模式创建(本质还是内置构造函数)
function createPerson(name, age) { var o = new Object(); o.name = name; o.age = age; return o; } var person1 = createPerson("Nike", 29); -
自制构造函数创建
- 这里就相当于:直接用函数 A,搞个实例 C 当对象
function Person(name, age) { this.name = name; this.age = age; } var person1 = new Person("Nike", 29); console.log(person1.name); //Nike console.log(person1.__proto__.name); //undefined- 这里能打印出
person1.name,是因为 name 本身就是这个实例的私有属性,而原型上并不存在这个属性
- 这里能打印出
- 好处: 可用
instanceof操作符检测对象具体类型
- 这里就相当于:直接用函数 A,搞个实例 C 当对象
-
原型创建
-
这里相当于:手动改原型,再搞个实例 C 当对象
function Person() {} Person.prototype.name = "Nike"; Person.prototype.age = 20; Person.prototype.eat = function () { console.log("eat"); }; var person1 = new Person(); console.log(person1.name); //Nike console.log(person1.__proto__.name); //Nike- 这里能打印出
person1.name,是通过追溯原型上的属性找到的
- 这里能打印出
-
好处: 可让
所有实例共享其中的属性和方法
-
2. 检查对象属性
-
用
in检查对象中是否含某属性时,如果实例对象中没有但是原型中有,也会返回 trueconsole.log("属性" in 对象名); -
可用
hasOwnProperty()方法来检查实例对象自身中是否存在某属性,只有当自身含有时才返回 true对象名.hasOwnProperty("属性名"); -
如何列举属性
- keys 仅返回可遍历的属性
Object.keys(对象名); - getOwnPropertyNames 返回可遍历和不可遍历属性
Object.getOwnPropertyNames(对象名);
- keys 仅返回可遍历的属性
3. 对象的三种方法
实例方法 instanceFunc
- 是在构造函数
里面添加的:const Parent = function () { this.instanceFunc = function () { console.log("这个是实例方法"); }; }; - 只有实例才能访问(每个实例单独有一份)
const parent = new Parent(); parent.instanceFunc();
原型方法 protoFunc
-
是在构造函数
外面添加的:Parent.prototype.protoFunc = function () { console.log("这个是原型方法"); }; -
不仅实例能访问(所有实例共享一份)
-
而且构造函数本身也能访问
- 只不过要加.prototype,使其借助原型上访问,并且要用 call 传入 this,在无实例情况下指明 this 内涵
const parent = new Parent(); parent.protoFunc(); Parent.prototype.protoFunc.call();
静态方法 staticFunc
- 是在构造函数
外面添加的:Parent.staticFunc = function () { console.log("这个是静态方法"); }; - 只有构造函数才能访问(较少用到)
Parent.staticFunc();
4. 属性描述对象
-
是 js 提供的一个内部数据结构
-
用来描述一个具体对象的某个属性,控制它的一些行为
-
比如该属性是否可写、是否可遍历、是否可配置等等
-
例子
{ value: undefined, writable: true, enumerable: true, configurable: true, get: undefined, set: undefined }-
以上皆为默认值,这 6 个属性称为“元属性”
-
writable 可写
- 如果设置为 false,则 value 的值不可被重新赋值改变,强改的话严格模式下将报错
- 但如果 configurable 为 true,那还是可以通过 defineProperty 去内部修改 value 元属性的值来改变
-
enumerable 可遍历
- 如果设置为 false,则 for...in 循环、Object.keys()中将不会出现该属性,这时候可以借助
Object.getOwnPropertyNames()去返回不可遍历的;同时 JSON.stringify 也不会编码该属性
- 如果设置为 false,则 for...in 循环、Object.keys()中将不会出现该属性,这时候可以借助
-
configurable 可配置
- 如果设置为 false,则会阻止改写这个属性描述对象,同时也无法删除该属性,但仍可以改变 value(前提是 writable 为 true),同时也允许 writable 从 true 改为 false(反向不行)
-
get
- 是一个 getter 函数,没有参数,设置它并提供返回值,将会在取值时触发并返回这个返回值
- 一旦自行定义了 get,那就不能将 writable 设为 true,也不能定义 value 属性,否则报错
-
set
- 是一个 setter 函数,设置它,将会在设置值时触发执行
- 会有一个参数,就是属性的值
-
-
-
如何获得?
- 使用静态方法:
Object.getOwnPropertyDescriptor(obj, "key1");- 第一个参数是 对象 obj
- 第二个参数是 目标属性值 key1
- 注意
- 只能用于自身属性,不能用于继承的
- 使用静态方法:
-
如何修改原有的?
-
单个修改,使用静态方法:
Object.defineProperty(obj, "key1", attrObj);- 第一个参数是 对象 obj
- 第二个参数是 目标属性值 key1
- 第三个参数是 新的属性描述对象
- 如果 obj 为{},那么会返回新的对象,否则在源对象上进行更新
-
批量修改,使用静态方法:
Object.definePropertys(obj, { key1: attrObj1, key2: attrObj2, }); -
注意
- 以上两种修改方法,如果不手动指定可写、可遍历、可配置,那一律默认为 false!!!
-
-
如何判断某个属性是否可遍历
- 使用原型方法
对象实例.propertyIsEnumerable();- 只能用于自身属性,对于继承的一律返回 false
- 使用原型方法