红宝书第八章:对象、类和面向对象编程

属性的类型:

js使用一些内部特性来描述属性的特征,但是不能直接访问。

属性分两种:数据属性 和 访问器属性

1.数据属性

数据属性包含一个保存数据值的位置。

数据属性有4个特性描述它的行为:

  • [[Configurable]] 表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为访问器属性。
  • [[Enumerable]] 表示属性是否可以通过 for-in 循环返回。
  • [[Writeable]] 表示属性的值是否可以被修改。
  • [[Value]] 包含属性实际的值。

要修改属性的默认特性,需要使用Object.defineProperty()。在调用 Object.defineProperty()时,configurable、enumerable 和 writable 的值如果不指定,会都默认为 false。

2.访问器属性

包含一个getter 和一个setter函数,必须使用 Object.defineProperty()来定义。

  • [[Get]]:获取函数,在读取属性时调用。默认值为 undefined。
  • [[Set]]:设置函数,在写入属性时调用。默认值为 undefined。

读取属性的特性

Object.getOwnPropertyDescriptor() 获得指定属性的属性描述符。

let  book = {};
Object.defineProperties(book,{
    year_:{
        value:2017,
    },
    edition:{
        value:1
    },
    year:{
        get:function(){
            return this.year_;
        },
        set:function(newValue){
            if(newValue>2017){
                this.year_ = newValue;
                this.edition += newValue - 2017;
            }
        }
    }
})

let descriptor = Object.getOwnPropertyDescriptor(book,'year_');
console.log('descriptor.value',descriptor.value);  // 2017
console.log('descriptor.configurable',descriptor.configurable);  // false
console.log('descriptor.enumerable',descriptor.enumerable); // false
console.log('descriptor.writable',descriptor.writable); // false

let descriptor2 = Object.getOwnPropertyDescriptor(book,'year');
console.log('descriptor2.value',descriptor2.value);  //undefined
console.log('typeof descriptor2.get',typeof descriptor2.get); // function

合并对象:

ES6 :Object.assign() —— 将源对象中 可枚举属性(Object.propertyIsEnumerable() 返回true) 和 自有属性 (Object.hasOwnProperty()返回true)复制到目标对象。

对象解构:

let person = {
    name:'ZY',
    age:25
}

let {name,age} = person;
console.log(name,age);


let {name:personName,age:personAge} = person;
console.log(personName,personAge); 

let { job }  = person;
console.log(job);  // 如果没有定义就是undefined


let { job='teacher' }  = person;
console.log(job);  // 'teacher' 可以设定默认值


let { _ } = null; // TypeError  null和undefined不能解构
let { _ } = undefined; // TypeError 

创建对象:

构造函数模式:

new ,使用new方式调用构造函数会执行以下操作:

  • 创建一个新对象
  • 将新对象内部的prototype指向构造函数的prototype属性
  • 构造函数内部的this指向这个新对象。
  • 如果构造函数返回非空对象,则返回该对象,否则,返回刚创建的对象。

1.构造函数 也是函数。 任何函数只要使用new调用就是构造函数。

2.构造函数的问题:

原型模式:

每个函数都会创建一个prototype属性,这个属性是一个对象。包含应该由特定引用类型的实例 共享的属性和方法。实际上,这个对象就是通过调用构造函数创建的对象的原型。使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。原来在构造函数中直接赋给对象实例的值,可以直接赋值给它们的原型。

hasOwnProperty() :用于确定属性是在实例上还是原型上(继承自Object)

如果属性是存在于对象实例上,返回true

原型和in操作符:

in操作符:

  1. 单独使用: 判断是否可以通过对象访问指定属性。 无论属性是在实例上还是原型上。(可以通过原型链查找)

所以in和hasOwenProperty()属性可以用于判断属性是在原型上还是实例上。

  1. for-in: 可以通过对象访问且可被枚举的属性 。包括实例属性和原型属性

Obejct.keys():可获得对象上所有可枚举实例属性。

Object.getOwnPropertyNames() :可以获得所有实例属性,无论可否枚举。

Object.getOwnPropertySymbols():可以获取使用symbol命名的实例属性。

属性枚举顺序:

Object.keys() 和 for-in 枚举顺序不确定,取决于JS引擎。

Object.getOwenPropertyNames()和 Object.getOwenPropertySymbols() 顺序:先按照升序枚举数值键,然后以插入顺序枚举字符串和符号键。

对象的迭代:

Object.values() 返回对象值的数组。

Object.entries() 返回键值对的数组。

重写对象原型:

要注意constructor属性。

继承:

一般继承分为 接口继承 和 实现继承。

JS中只有实现继承,主要是通过原型链实现的。

每个构造函数都有一个原型对象,原型有 一个属性指回构造函数,而实例有一个内部指针指向原型。如果原型是另一个类型的实例呢?那就意味 着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函 数。这样就在实例和原型之间构造了一条原型链。这就是原型链的基本构想。

原型与实例的关系:

  1. instanceof 操作符 :如果一个实例的原型链中出现过相应的构造函数,那么返回true

2. isPrototypeOf()

继承:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值