JS高级--原型与原型链

本文详细探讨了JavaScript中的原型概念,包括函数的prototype属性和对象的__proto__属性,阐述了原型链的工作原理及其在属性查找中的角色。此外,还介绍了instanceof操作符的使用以及原型继承的概念,并提供了相关的面试题以加深理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、原型

函数的prototype属性

* 每个函数都有一个prototype属性,它默认指向一个object空对象(即称为:原型对象)

* 原型对象中有一个constructor属性,它指向函数对象

function Fun() {}
console.log(Fun.prototype) // 默认指向一个空对象

// 原型对象中有一个constructor属性,它指向函数对象	
console.log(Fun === Fun.prototype.constructor) // true
			
// 给原型对象添加属性(一般是方法),实例对象可以访问到这个属性
Fun.prototype.text = function() {
    console.log('text方法')
}
const fun = new Fun()
fun.text() // text方法

二、显式原型与隐式原型

1、每个函数function都有一个prototype属性,即显示原型属性(函数创建时加上的)

function Fn() {} // 内部语句:this.prototype = {}
console.log(Fn.prototype)

2、每个实例对象都有一个__proto__属性,可称为隐式原型属性(创建对象时加上的)

const fn = new Fn() // 内部语句:this.__proto__ = Fn.prototype
console.log(fn.__proto__)

3、对象的隐式原型的值为其对应构造函数的显式原型的值

console.log(Fn.prototype === fn.__proto__) // true

4、内存结构图

5、总结

* 函数的prototype属性:在定义函数时自动添加的,默认值是一个空Object对象

* 对象的__proto__属性:创建对象时自动添加的,默认值为构造函数的prototype属性值

* 程序员能够直接操作显式原型,但不能直接操作隐式原型(ES6之前)


三、原型链

1、原型链

  * 访问一个对象的属性时,
    * 先在自身属性中查找,找到返回
    * 如果没有, 再沿着__proto__这条链向上查找, 找到返回
    * 如果最终没找到, 返回undefined
  * 别名: 隐式原型链
  * 作用: 查找对象的属性(方法)

 2、构造函数/原型/实例对象的关系(图解)

var o1 = new Object();
var o2 = {};

 3、构造函数/原型/实例对象的关系2(图解)

function Foo(){  } // 相当于 var Foo = new Function(), 所有的函数都是这么来的
// 说明所有函数对象既有prototype也有__proto__
// 所有实例对象(函数对象)的隐式原型指向其构造函数(Function)的显式原型
// 所有函数对象的隐式原型指向Function的显式原型

// var Function = new Function()
// Function是自己创造自己, 所以Function的隐式原型指向自身(构造函数)的显式原型

// 1. 函数的显示原型指向的对象默认是空Object实例对象(但Object不满足)
console.log(Fn.prototype instanceof Object) // true
console.log(Object.prototype instanceof Object) // false Object.prototype.__proto__ = null
console.log(Function.prototype instanceof Object) // true

// 2. 所有函数都是Function的实例(包含Function)
console.log(Function.__proto__===Function.prototype)

// 3. Object的原型对象是原型链尽头
console.log(Object.prototype.__proto__) // null

4、原型继承

构造函数的实例对象自动拥有构造函数原型对象的属性(方法)(利用的就是原型链)

5、原型链--属性问题

* 读取对象的属性值时: 会自动到原型链中查找
* 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
* 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上

四、探索instanceof

1、instanceof是如何判断的

* 表达式:A instanceof B

* 如果B函数的显式原型对象在A对象的原型链上,返回ture,否则返回false

案例一:

function Foo() {  }
var f1 = new Foo();
console.log(f1 instanceof Foo);  // true
console.log(f1 instanceof Object); // true

 案例二:

console.log(Object instanceof Function); // true
console.log(Object instanceof Object); // true
console.log(Function instanceof Function); // true
console.log(Function instanceof Object); // true

function Foo() {}
console.log(Object instanceof  Foo); // false

这个是最完整的关系图

自我思考:Object() = var Object = new Function,函数都是通过Function()产生的

 五、补充(面试题)

测试题一:

var A = function() {}

A.prototype.n = 1

var b = new A()

A.prototype = {

  n: 2,

  m: 3

} // 不会影响以前创建的实例对象,但会影响后面创建的实例对象
var c = new A()

console.log(b.n, b.m, c.n, c.m) // 1 undefine 2 3

测试题二:

 var F = function(){};

  Object.prototype.a = function(){

    console.log('a()')

  };

  Function.prototype.b = function(){

    console.log('b()')

  };

  var f = new F();

  f.a() // a()

  f.b() // 报错

  F.a() // a()

  F.b() // b()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值