原型链 & this 指向总结

一、JavaScript 原型链

1. 基础概念

  • 每个对象都有一个内部属性 [[Prototype]] ,可以通过 __proto__Object.getPrototypeOf(obj) 访问。
  • 构造函数 Foo 有一个 .prototype 属性,指向一个对象,这个对象作为实例的原型。
  • 查找属性的顺序:实例 → 原型 → 原型的原型 … → Object.prototype → null

2. 典型例题示意

 1function Foo() {}
 2Foo.prototype.a = 1
 3
 4const foo = new Foo()
表达式值/说明
foo.a1 (实例自身没有,去原型链找)
foo.__proto__Foo.prototype
Foo.__proto__Function.prototype
Foo.prototype.__proto__Object.prototype

原型链示意图

 1foo ---> Foo.prototype ---> Object.prototype ---> null
 2Foo ---> Function.prototype ---> Object.prototype ---> null

3. 原型链继承问题

 1function A() {}
 2function B() {}
 3A.prototype.x = 10
 4B.prototype = new A()
 5const b = new B()
 6
 7console.log(b.x)
 8console.log(b.constructor === B)
  • B.prototype = new A() 后,b 的原型链:
 1b ---> B.prototype (new A()) ---> A.prototype ---> Object.prototype ---> null
  • constructor 被覆盖,需手动修复:
 1B.prototype.constructor = B

4. 函数对象 vs 实例对象原型链

 1function Foo() {}
 2const f = new Foo();
 3
 4console.log(Foo.__proto__ === Function.prototype); 
 5console.log(f.__proto__ === Foo.prototype);        
  • 函数对象链:函数本身是可调用对象 → Function.prototype
  • 实例对象链:普通对象 → Foo.prototypeObject.prototype

可视化图:

 1函数对象 Foo: Foo ---> Function.prototype ---> Object.prototype ---> null
 2实例对象 f: f ---> Foo.prototype ---> Object.prototype ---> null

记忆:函数对象和实例对象是两条独立链,方法挂在 Function.prototype 不会被实例继承


二、this 指向

1. 基本规则

调用方式this 指向
普通函数调用全局对象(浏览器是 window,严格模式下 undefined)
对象方法调用调用者对象
构造函数调用(new)新创建的实例
call/apply/bind 调用手动指定对象
箭头函数定义时的词法作用域(外层 this)

2. 典型题分析

题例:普通函数 vs arguments

 1var length = 10
 2function fn() { console.log(this.length)
 3
 4const obj = {
 5  length: 5,
 6  method: function(fn) {
 7    fn()
 8    arguments[0]()
 9  }
10}
11obj.method(fn, 1)
调用this输出
fn()window/global10
arguments[0]()arguments2
  • 关键点arguments[0]() 调用者是 arguments 对象,this === arguments,而 arguments.length = 2

原型链 & this 综合题

 1Function.prototype.getName = function(){ return this.name; }
 2function Foo() {}
 3const f = new Foo();
 4
 5console.log(Foo.getName()); 
 6console.log(f.getName());   
  • Foo 是函数对象 → 可继承 Function.prototype
  • f 是实例 → 继承自 Foo.prototype(普通对象),Function.prototype 不在其链上

3. this 指向可视化

 1普通函数
 2fn() 
 3this ---> window/global
 4
 5对象方法
 6obj.method() 
 7this ---> obj
 8
 9构造函数
10new Foo() 
11this ---> 新建实例 f
12
13arguments 调用
14arguments[0]() 
15this ---> arguments

三、记忆技巧

  1. 原型链

    • 函数对象 → Function.prototype → Object.prototype
    • 实例对象 → 构造函数.prototype → Object.prototype
    • 构造函数 prototype 上挂的方法 → 实例可用
  2. this

    • “谁调用指向谁”是最核心原则
    • 箭头函数不看调用者,固定绑定外层 this
    • arguments 是一个对象,调用其中的函数时 this 指向 arguments

四、总结表

概念/题型关键点/技巧
原型链查找属性实例 → 实例.proto → … → Object.prototype
构造函数.prototype实例的原型对象
函数对象原型链Foo.proto → Function.prototype → Object.prototype
实例对象原型链f.proto → Foo.prototype → Object.prototype
this 普通函数调用window / undefined
this 对象方法调用调用者对象
this 构造函数 new 调用新建实例
this call/apply/bind手动指定对象
箭头函数继承定义时的 this

个人笔记记录 2021 ~ 2025