美文网首页
上卷 第二部分 第三章 对象

上卷 第二部分 第三章 对象

作者: nymlc | 来源:发表于2019-05-28 23:20 被阅读0次

语法

  1. 文字语法
var obj = {
    key: value
}
  1. 构造语法
var obj = new Object() // new Object、Object
obj.key = value

类型

一般而言就六种语言类型:string、boolean、number、null、undefined、object,还有ES6新增的symbol(符号)
若是忽视typeof null === 'object'(js多年的bug,null的二进制全为0,而二进制的前三位为0的话会被判为对象)的话,那么JavaScript万物皆对象
内置对象
JavaScript提供的一些函数:String、Number、Boolean、Function、Date、Error、RegExp、Array、Object
null、undefined是没有构造语法的,Date、Error则只有构造语法,俩者兼得的话其文字语法可以直接访问属性和方法(会自行处理成对应包装对象)

内容

对象的内容(value)一般而言不会存储在对象容器的内部。存储在对象内部的是(key),它们就像指针(其实是引用,js没有指针)一样指向内容真正的存储位置(就键访问和属性访问

使用属性访问的话,属性名会被toString

  1. 可计算属性名
var prefix = 'key'
var obj = {
    [prefix + '1']: value
}

一般而言主要用于Symbol

  1. 属性与方法
    在Java之类的一些语言中,属于对象的函数通常称之为方法,所以若是访问的是一个函数,那么属性访问也叫方法访问,该方法(函数)和普通函数没什么区别,除了this的绑定有点影响

函数不可能属于一个对象(都是引用),所以不能称之为方法

  1. 数组
    其实数组就是个普通对象,只是内置了一下有了数组的特性,有点像当年C语言实现数组功能一样。
    它正常的key也就是期望的key应该是数值(自然数),只要是符合这个的,length会自动++。key值类自然数的话也是会自行转成期望的下标。delete操作的话,length不会变化
  2. 复制对象
    这是个很复杂的问题。深拷贝、浅拷贝(和拷贝深度无关)。还有发生的死循环(循环引用)
  • JSON安全(就是看起来像JSON的,说的全面点就是可以被序列化(看最下文)一个JSON字符串,然后根据这个字符串可以解析出一个结构和值一样的对象)的对象可以序列化,然后反序列化就完成了复制
  • ES6的Object.assign可以完成浅拷贝
  • 自行实现
function deepClone(source) {
    if (typeof source === 'object') {
        const targteObj = source.constructor === Array ? [] : {}
        for (const key in source) {
            if (source.hasOwnProperty(key)) {
                if (source[key] && typeof source[key] === 'object') {
                    targteObj[key] = deepClone(source[key])
                } else {
                    targteObj[key] = source[key]
                }
            }
        }
        return targteObj
    } else {
        return source
    }
}
  1. 属性描述符(数据描述符)
    Object.getOwnPropertyDescriptor,获取属性描述
  • Writable:是否可以修改属性值(value),若是false的话,在严格模式下会报TypeError其实和setter为空一样,只是要抛出TypeError
  • Configurable:是否可以使用defineProperty修改属性描述符,若是false的话会报TypeError不可逆

有个例外,configurable: false时还是可以把writable从true改为false

configurable: false会禁止删除(delete)这个属性
delete不能直接释放内存,它只是在delete的属性没有引用时释放,内存管理通过断开引用来间接完成内存释放

  • enumerable:属性是否可被枚举(for in循环),值得注意的是。for、for of、forEach等数组操作不影响
  1. 不变性
  • 对象常量(不可修改、才得以或者删除):writable: false、configurable: false,可以创建一个常量属性
var obj = {}
Object.defineProperty(obj, 'key', {
    value: 'value',
    writable: false,
    configurable: false
})
  • 禁止扩展(不可添加新属性,保留现有属性):Object.preventExtensions(obj)
  • 密封(禁止扩展+configurable: false):Object.seal(obj)
  • 冻结(密封+writable: false):Object.freeze(obj)

不可变仅作用在对象本身以及其直接属性,至于引用的其它对象是无效的

var obj = {
    num: 1,
    arr: [1]
}
Object.freeze(obj)
obj.num = 2
console.log(obj.num) // 1
obj.arr.push(2)
console.log(obj.arr) // [1, 2]
  1. [[Get]]
var obj = {
    num: 1
}
obj.num // 2

obj.num是在obj上实现了[[Get]]操作(类似函数调用:[[Get]])。对象默认的[[Get]]操作会先在对象中查找是否具有这个属性,有的话就返回,没有的话proto继续找。实在找不到返回undefined。比较尴尬的是,若是这个属性就是undefined,就不能区分到底是哪种情况返回的undefined

  1. [[Put]]
    并不仅仅触发[[Put]]来设置或者创建属性。实际上取决很多因素,最大的因素是对象之中是否存在这个属性
  • 属性是否存在访问描述符?如果存在setter就调用setter
  • 如果writable: false,在非严格模式下不生效,在严格模式下报TypeError
  • 如果不是以上俩情况,就设置值

如果不存在这个值的话就复杂了

  1. Getter和Setter
    若是给一个属性定义了这俩个至少一个,这个属性就会定义为访问描述符。这时候就会忽略valuewritable,而是关心setget(以及configurable和enumerable)
    一般而言俩者都定义才好
// 俩种定义方式
var obj = {
    get a() {
        return 2
    }
}
Object.defineProperty(obj, 'b', {
    get() {
        return this.a * 2
    }
})
obj.a // 2
obj.b // 4
  1. 存在性
    判断属性是否存在,即obj.a === undefined是哪种情况
var obj = {
    a: 2
}
// 会检查整个原型链
'a' in obj // true
'b' in obj // false
// 只会检查对象本身
obj.hasOwnProperty('a') // true
obj.hasOwnProperty('b') // false
// Object.create(null),这种情况下的对象不能链接到Object.prototype,自然不能调用hasOwnProperty方法。可用call
  • 枚举:值得注意的是,enumerable: false虽然不会出现在for in循环内,不过还是可以用in来判定属性是否存在。
var obj = {
    a: 2
}
// 以下均只作用于本对象。不作用于原型链
// 判断属性是否存在本对象之中,且enumerable: true
obj.propertyIsEnumerable('a') // true
// 返回一个包含所有可枚举属性的数组
Object.keys(obj) // ['a']
// 返回一个包含所有属性的数组
Object.getOwnPropertyNames(obj) // ['a']

遍历

  • for in:遍历对象可枚举属性
  • for:遍历数组下标(其实也是属性)
  • forEach、every(一直运行直到返回false)、some(一直运行直到返回true)
  • for of:直接遍历值(必须本身定义了迭代器(@@iterator))
// 数组
var arr = [1, 2, 3]
var it = arr[Symbol.iterator]()

it.next() // {value: 1, done: false}
it.next() // {value: 2, done: false}
it.next() // {value: 3, done: false}
it.next() // {value: undefined, done: true}
// 对象
var obj = {
    key0: 1,
    key1: 2,
    key2: 3
}
Object.defineProperty(obj, Symbol.iterator, {
    writable: false,
    enumerable: false,
    configurable: false,
    value: function() {
        var o = this
        var idx = 0
        var ks = Object.keys(o)
        return {
            next: function() {
                return {
                    value: o[ks[idx++]],
                    done: idx > ks.length
                }
            }
        }
    }
})
var it = obj[Symbol.iterator]()

it.next() // {value: 1, done: false}
it.next() // {value: 2, done: false}
it.next() // {value: 3, done: false}
it.next() // {value: undefined, done: true}
// for of循环
for (var v of obj) {
    console.log(v)
}

序列化

对象其实就是字节,字节存储的是对象的数据信息、类型以及存储在其内的数据信息

var obj = {
    key: value
}

就比如这个对象,它内容是存储在内存地址中,obj存储的只是这个内存地址的映射(引用),断电了自然就没了。那么就需要把它转成字符串,就可以存储在硬盘之上。服务器的JSON也是序列化之后传输到前端,然后反序列化就好了。


百度百科序列化定义

相关文章

  • 上卷 第二部分 第三章 对象

    语法 文字语法 构造语法 类型 一般而言就六种语言类型:string、boolean、number、null、un...

  • 《被动》目录 完结

    《被动》上卷 知有飘零 目录 《被动》 上卷 楔子 《被动》上卷 第一章 囚鸟 《被动》上卷 第二章 相聚 《被动...

  • 《被动》下卷 决不饶恕 第三章 交易

    《被动》上卷 知有飘零 目录 - 简书 《被动》下卷 决不饶恕 第二章 目击者 - 简书 第三章 交易 甘树兴佝偻...

  • 深入浅出Object.defineProperty()

    讲解大致会根据下图展开 本文部分参考了书籍《你不知道的javascript》上卷 对象的定义与赋值 经常使用的定义...

  • 深入浅出Object.defineProperty()

    讲解大致会根据下图展开 本文部分参考了书籍《你不知道的javascript》上卷 对象的定义与赋值 经常使用的定义...

  • 《关键冲突》读书笔记2

    第二部分安全应对,关键冲突时如何行动 第三章问题描述:如何准备关键冲突 根据第二部分的导读部分,第三章的内容主要是...

  • 读书笔记分类目录

    红宝书 第二章html中使用JavaScript第三章基本概念第四章变量,作用域和内存问题 你不知道的js上卷 链...

  • 《千闻.静树》目录

    目录 上卷 【千闻.静树】楔子 【千闻.静树】 第一章命运之书 【千闻.静树】第二章 还乡 【千闻.静树】第三章 ...

  • 《被动》上卷 知有飘零 第三章 故心人易变

    《被动》上卷 知有飘零 第二章 相聚 - 简书 《第三章故心人易变》 我们从私房菜馆出来,一路上吴毅智兴致极高,侃...

  • 领略不一样的电子表格Numbers

    第一章 了解 Numbers 第二章 走进 Numbers 第三章 表格对象 第四章 单元格对象 第五章 图表对象...

网友评论

      本文标题:上卷 第二部分 第三章 对象

      本文链接:https://www.haomeiwen.com/subject/yhiqzqtx.html