this和对象原型
关于this
使用this的原因:this提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将API设计得更加简洁并且易于复用
- this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用
- 当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在函数执行的过程中用到。
this解析
this绑定规则
默认绑定
- 独立函数调用。可以把这条规则看作是无法应用其他规则时的默认规则
- 如果使用严格模式,那么全局对象将无法使用默认绑定,因此this会绑定到undefined
隐式绑定
- 当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象
显示绑定
- call
- apply
- bind
new绑定
- 在内存中创建一个新对象
- 这个新对象内部的
[[Prototype]]
特性被赋值为构造函数的prototype
属性 - 构造函数内部的this被赋值为这个新对象(即this指向新对象)
- 执行构造函数内部的代码(给新对象添加属性)。
- 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
优先级
- 函数是否在new中调用(new绑定)?如果是的话this绑定的是新创建的对象
- 是否通过call、apply(显式绑定)或者硬绑定调用
- 是否在某个上下文对象中调用(隐式绑定)
- 都不是的话,使用默认绑定
绑定例外
把null或者undefined作为this的绑定对象传入call、apply或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则
箭头函数中的this
- 箭头函数不使用this的四种标准规则,而是根据当前的词法作用域来决定this,具体来说,箭头函数会继承外层函数调用的this绑定(无论this绑定到什么)。
- 箭头函数的绑定无法被修改
对象
语法
声明式和构造式
- 唯一的区别是,在文字声明中你可以添加多个 键 / 值对,但是在构造形式中你必须逐个添加属性
内容
在引擎内部,这些值的存储方式是多种多样的,一般并不会存 在对象容器内部。存储在对象容器内部的是这些属性的名称,它们就像指针(从技术角度 来说就是引用)一样,指向这些值真正的存储位置
.
操作符- 通 常被称为“属性访问”
[]
操作符- 通常被称为“键访问”
数组
数组期望的是数值下标,不过它并不限制值的类型。如果添加了命名属性(非数值下标),数组的 length 值并不会发 生变化
复制
- 浅复制
- Object.assign() 方法的第一个参数是目标对象,之后还可以跟一个 或多个源对象。它会遍历一个或多个源对象的所有可枚举 的自有键,并把它们复制(使用 = 操作符赋值)到目标对象,最 后返回目标对象
- 深复制
属性描述符
- value
- writable
- enumerable
- configurable
不变性
- 对象常量
- writable:false
- configurable: false
- 禁止扩展
- Object.preventExtensions()
- 密封
- Object.seal(..) 会创建一个“密封”的对象,这个方法实际上会在一个现有对象上调用 Object.preventExtensions(..) 并把所有现有属性标记为 configurable:false
- 冻结
- Object.freeze(..) 会创建一个冻结对象,这个方法实际上会在一个现有对象上调用 Object.seal(..) 并把所有“数据访问”属性标记为 writable:false,这样就无法修改它们 的值
存在性
- in 操作符会检查属性是否在对象及其 [[Prototype]] 原型链中
- hasOwnProperty(..) 只会检查属性是否在 myObject 对象中,不会检查 [[Prototype]] 链
遍历
- forEach() 会遍历数组中的所有值并忽略回调函数的返回值
- every() 会一直运行直到 122 | 第 3 章 回调函数返回 false
- some() 会一直运行直到回调函数返回 true
- for..of 循环首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的 next() 方法来遍历所有返回值
ES6 中的符号 Symbol.iterator 来获取对象的 @@iterator 内部属 性,但是 @@iterator 本身并不是一个迭代 器对象,而是一个返回迭代器对象的函数