Simonzhangs' blog Simonzhangs' blog
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Simonzhangs

前端学习探索者
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript文章

    • 33个非常实用的JavaScript一行代码
    • new命令原理
    • ES5面向对象
    • ES6面向对象
    • 多种数组去重性能对比
    • JS随机打乱数组
    • 判断是否为移动端浏览器
    • 将一维数组按指定长度转为二维数组
    • 防抖与节流函数
    • JS获取和修改url参数
    • 比typeof运算符更准确的类型判断
    • 常见面试题

      • 四级文件(测试)
      • 原型与原型链
      • JS数据类型
      • call、apply、bind
      • JavaScript运行机制
      • promise
      • JS中在new的时候发生了什么
  • 学习笔记

  • 前端
  • JavaScript文章
  • 常见面试题
simonzhangs
2022-03-30

原型与原型链

# 原型与原型链关系

prototype:原型;

__proto__:原型链(内置对象),实际上是原型的链接点;

从属关系: prototype:从属于函数,函数的一个属性;平时说的函数的原型,实际上就是函数的prototype属性,它本身是一个对象;

__proto__: 从属于对象,对象Object的一个属性,本身也是一个对象。

对象的__proto__保存着该对象的构造函数的prototype。

# 实例证明两者关系

声明一个函数,来验证函数是否有prototype属性:

function Test() {}
console.log(Test.prototype)
1
2

打印结果:

{constructor: ƒ}
constructor: ƒ Test()
__proto__: Object
1
2
3

说明函数只要构造出来,便存在prototype属性;同时prototype也是一个对象,因此存在__proto__属性;

现在利用函数和关键字new 构造出一个对象实例,判断是否存在__proto__属性:

const test = new Test()
console.log(test.__proto__)
1
2

打印结果:

{constructor: ƒ}
constructor: ƒ Test()
__proto__: Object
1
2
3

说明对象创建时便存在__proto__属性;

console.log(test.__proto__ === Test.prototype) //true
1

验证了对象的__proto__属性保存了该对象的构造函数的prototype。


由于函数的prototype属性本身也是对象,因此也存在__proto__属性,在上面已经验证过,继续研究该__proto__属性是否有保存prototype,以及是谁的:

console.log(Test.prototype.__proto__);
1

打印结果:

{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
...
1
2
3
4

根据打印的结果可以看出,对于的是构造函数Object的prototype,通过如下打印结果验证:

console.log(Test.prototype.__proto__ === Object.prototype); // true
1

但是通过__proto__走到Obejct后,实际上已经走到了最顶层,Object.prototype是最顶层了,该原型上不存在__proto__属性了:

console.log(Object.prototype.__proto__) //null
1

# 原型与原型链继承

function Test() {
    this.a = 1;
}

Test.prototype.b = 2;

Object.prototype.c = 3

const test = new Test();

console.log(test);
1
2
3
4
5
6
7
8
9
10
11

打印结果:

Test {a: 1}
a: 1
__proto__:
b: 2
constructor: ƒ Test()
__proto__:
c: 3
...
1
2
3
4
5
6
7
8

原型链本质上是:以一个对象为基准,以__proto__为链接,一直到Object.prototype为止这个链,称为原型链。

继承的体现:能打印出b、c,他们不在构造函数里面,如果在构造函数中没有,就去原型链__proto__上去继承,直到Object.prototype,这就是原型链继承。

console.log(test.a); //1
console.log(test.b); //2
console.log(test.c); //3
1
2
3

# Function 和 Object 的特殊性

FUnction 和 Object 是函数也是对象。

之前将Test()看做函数来考虑的,但它同时也是对象,因此也存在__proto__属性:

console.log(Test.__proto__); //ƒ () { [native code] }
console.log(Test.__proto__ === Function.prototype); //true
1
2

打印结果显示该属性为函数,并且与等同于Function.prototype,即表示Test()是由Function构造出来的。(const Test = new Function())

同时Function也是函数,因此也有__proto__ 和 prototype,这里需要注意,在底层规定两者是相等的:

console.log(Function.prototype === Function.__proto__); //true
1

同时对于Object除了是对象外,也是函数,故存在__proto__属性; 当创建对象时,相对于new Object:

const obj = {} // =>等同于
const obj = new Object(); //function
1
2
console.log(typeof Object); //function
console.log(Object.__proto__ === Function.prototype); //true
1
2

可以得知Object也是由Function构造而来的;在new Object时候底层就是由Function构造而来的。

结合可以得出:Object.__proto__ === Function.__proto__;

# 判断对象的属性是否存在

判断对象本身是否存在属性使用hasOwnProperty方法;

console.log(test.hasOwnProperty('a')); //true
console.log(test.hasOwnProperty('b')); //true
console.log(test.hasOwnProperty('c')); //false
1
2
3

判断对象的整个原型链上是否存在,使用in方法:

console.log('a' in test); //true
console.log('b' in test); //true
console.log('c' in test); //true
1
2
3
编辑 (opens new window)
上次更新: 2022/05/17, 21:50:47
四级文件(测试)
JS数据类型

← 四级文件(测试) JS数据类型→

最近更新
01
一些有意思的类比
06-16
02
the-super-tiny-compiler解析
06-06
03
计算机编译原理总概
06-06
更多文章>
Theme by Vdoing | Copyright © 2021-2022
蜀ICP备2021023197号-2
Simonzhans | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
  • 飙升榜
  • 新歌榜
  • 云音乐民谣榜
  • 美国Billboard榜
  • UK排行榜周榜