this和对象原型第三章

第三章:对象


语法


-声明(字面)形式

var myObj = {

        key: value

        //一次性可以添加多个键/值对,常用

};

-构造形式

var myObj =newObject();
myObj.key = value;//必须一个个添加属性

 

类型


-对象是大多数JS程序依赖的基本构建块

-JS六种主要类型(语言规范中的”语言类型”)

       1.string

       2.number

       3.boolean

       4.null

       5.undefined

       6.object

-简单基本类型(12345)自身不是object

-null实际上是它自己的基本类型,但typeofnull会错误返回”object”(bug)

-错误论断:JavaScript中的一切都是对象

-复杂基本类型

       1.function对象子类型(技术上称”可调用对象”),“头等(first class)”类型

       2.数组内容组织上更加结构化

 

内建对象


-其他的对象子类型称为内建对象

       1.String

       2.Number

       3.Boolean

       4.Object

       5.Function

       6.Array

       7.Date

       8.RegExp

       9.Error

-仅仅是内建的函数,都可以被用作构造器(new),结果是一个新构建的相应子类型的对象

-必要时语言会自动将“string”基本类型强制转换为String对象类型

-JS社区绝大部分人强烈推荐尽可能使用字面形式的值

-Date值仅可以由它们的构造对象形式创建(没有对应的字面形式)

-仅仅在你需要使用额外的选项时使用构建形式

 

内容


-对象的内容由存储在特定命名的位置上的(任意类型的)值组成

-称这些值为属性

-值通常不存储在容器对象内部,存的是属性名称

-像指针一样(reference引用)指向值存储的地方

var myObject = {
        a:2
};
myObject.a;              // 2
myObject["a"];   // 2

-.a:“属性(property)”访问

       1.a需要是一个标识符(Identifier)兼容的属性名

       2.不合法只能用键访问

-[“a”]:“键(key)”访问

       1.对象中属性名总是字符串

       2.对象和数组使用的数字别搞混,都会使字符串

 

计算型属性名


-将计算表达式作为键名称要用键访问

-ES6加入了计算型属性名,指定表达式为名称

var prefix ="foo";
var myObject = {
        [prefix +"bar"]:"hello",
        [prefix +"baz"]:"world"
};
myObject["foobar"]; // hello
myObject["foobaz"]; // world

-最常见用法用于ES6的Symbol

       1.新的基本类型

       2.强烈不鼓励使用实际值(理论上因JS引擎不同而不同)的情况

 

属性(Property)vs.方法(Method)


-访问对象的属性都是一个属性访问(函数也是属性访问,不会在访问时成为方法)

-函数不会属于对象,只是函数的一个引用

-ES6加入了super引用(静态绑定通常和class一起使用)

 

数组


-组织更加结构化,数字索引(下标)

-可以添加命名属性,不会改变length的值

-命名为数字会成为数字索引,改变数组内容(length改)

 

复制对象


-浅(shallow copy引用)拷贝深(deep copy)拷贝

-不同JS框架标准不同

-一个解决方案,JSON安全的对象

       1.被序列化为一个JSON字符串,之后还可以被重新解析为相同结构和值的对象

       2.ES6为浅拷贝定义了Object.assign(...)

              -接收目标对象作为第一个参数,一个或多个源对象作为后续参数

              -源对象上迭代所有的可枚举enumerable,own keys(直接拥有的键)

              -拷贝到目标对象(仅通过=赋值)

              -任何在源对象属性的特殊性质在目标对象都不会保留

      

属性描述符(Property Descriptors)


-ES5中所有的属性都用属性描述符来描述

-创建一个普通属性,可以有加上各种性质

-可以用Object.defineProperty()来添加新属性,或用期望的性质修改既存的属性

var myObject = {};

Object.defineProperty( myObject, "a", {

        value:2,

        writable:true,

        configurable:true,

        enumerable:true

} );

myObject.a; // 2

-可写性(Writable)

       1.控制你改变属性值的能力

var myObject = {};

Object.defineProperty( myObject, "a", {

        value:2,

        writable:false, // 不可写!

        configurable:true,

        enumerable:true

} );

myObject.a =3;

myObject.a; // 2 use strict会得到一个错误TypeError

-可配置性(Configurable)

       1.可配置可以使用相同的defineProperty()工具修改描述符定义

       2.false单向不可撤销,再调用defineProperty()会发生TypeError

       3.false可写性可以从true到false,反向不行

       4.false阻止使用delete操作符移除既存属性的能力

       5.delete移除引用,仅仅是一个对象属性移除操作,用于释放内存不恰当

-可枚举性(Enumerable)

       1.控制一个属性是否能在特定的对象-属性枚举操作中出现

 

不可变性(Immutability)


-有时我们希望将属性或对象设置为不可改变的

-ES5有几种不同的微妙方式

1.创建的都是浅不可变性

2.仅影响对象和它的直属属性的性质

3.拥有其他对象的引用不会受影响,仍然可变

-对象常量(ObjectConstant)

       1.writable:false和configurable:false组合

       2.创建一个作为对象属性的常量(不能被改变,重定义或删除)

-防止扩展(PreventExtensions)

       1.防止被添加新属性,并保留其他既存的对象属性

       2.调用Object.preventExtensions(..)

       3.非strict mode无声失败,strict mode抛出TypeError

-封印(Seal)

       1.调用Object.preventExtensions(..)并configurable:false

       2.不能添加,配置,删除属性,可以修改值

-冻结(Freeze)

       1.调用Object.seal(..)并writable:false

       2.从自身获得的最高级别的不可变性

       3.深度冻结:递归全部冻结


[[Get]]


       1.属性访问细节

var myObject = {

        a:2

};

myObject.a; // 2

       2.先执行一个[[Get]]操作,对象中找到属性返回相应的值

       3.(遍历[[Prototype]]链)如果任何方法都找不到,返回undefined

       4.引用在可用词法作用域无法解析的变量会抛出ReferenceError


[[Put]]


       1.给一个对象的属性赋值

       2.属性存在,[[Put]]算法会大致检查:

              1.属性时访问器描述符吗,是且是setter,调用setter

              2.writable为false吗,是在非strict下无声失败,strict下抛出TypeError

              3.否则像平常一样设置既存属性的值

 

Getters与Setters


-ES5引入的方法覆盖put,get这些默认操作的一部分,针对属性

-Getter调用一个隐藏函数来取得值的属性

-Setter调用一个隐藏函数来设置值的属性

-一个属性定义为拥有getter/setter,定义就成为了”访问器描述符”

-value和writable性质没有意义而被忽略,而是set,get(configurable,enumerable)性质

var myObject = {

        // `a` 定义 getter

        geta() {

                 returnthis._a_;

        },

        // `a` 定义 setter

        seta(val) {

                 this._a_ = val *2;

        }

};

myObject.a =2;

myObject.a; // 4

 

存在性(Existing)


-in操作符会检查属性是否存在于对象中或[[Prototype]]链对象遍历的更高层中

-hasOwnProperty(..)仅仅检查是否拥有属性,不检查[[Prototype]]链

-枚举(Enumeration)

       1.如果对象的属性被迭代时会被包含在内

       2.propertyIsEnumerable(..)测试一个给定属性名是否直接存于对象上且可枚举

       3.Object.keys(..)返回一个所有可枚举属性的数组

       4.Object.getOwnPropertyNames(..)返回一个所有属性的数组

 

迭代(Iteration)


-数字索引的数组中,典型的迭代办法是使用标准的for循环

var myArray = [1, 2, 3];

for (var i =0; i < myArray.length; i++) {

        console.log( myArray[i] );

}

// 1 2 3

-ES5加入了几个迭代帮助方法

       1.forEach(..)迭代所有值,忽略回调的返回值

       2.every(..)迭代到最后或当回调返回一个false(falsy)值

       3.some(..)迭代到最后或回调返回一个true(truthy)值

-ES6加入了for..of循环语法用来迭代数组和有定义迭代器的对象

var myArray = [ 1, 2, 3 ];

for (var v of myArray) {

        console.log( v );

}

// 1

// 2

// 3

       1.要被迭代的东西提供一个迭代器对象

       2.每次循环调用一次迭代器对象的next()对象

       3.@@iterator本身不是迭代器对象,是一个返回迭代器对象的方法

 



 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值