this和对象原型

关于this

使用this的原因:this提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将API设计得更加简洁并且易于复用

  • this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用
  • 当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在函数执行的过程中用到。

this解析

this绑定规则

默认绑定

  • 独立函数调用。可以把这条规则看作是无法应用其他规则时的默认规则
  • 如果使用严格模式,那么全局对象将无法使用默认绑定,因此this会绑定到undefined

隐式绑定

  • 当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象

显示绑定

  • call
  • apply
  • bind

new绑定

  • 在内存中创建一个新对象
  • 这个新对象内部的[[Prototype]]特性被赋值为构造函数的prototype属性
  • 构造函数内部的this被赋值为这个新对象(即this指向新对象)
  • 执行构造函数内部的代码(给新对象添加属性)。
  • 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。

优先级

  1. 函数是否在new中调用(new绑定)?如果是的话this绑定的是新创建的对象
  2. 是否通过call、apply(显式绑定)或者硬绑定调用
  3. 是否在某个上下文对象中调用(隐式绑定)
  4. 都不是的话,使用默认绑定

绑定例外

把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 本身并不是一个迭代 器对象,而是一个返回迭代器对象的函数

混合对象“类”