03-javascript基础----js原型和原型链

本文深入探讨JavaScript中的原型概念,包括原型对象、原型链的工作原理以及`instanceof`操作符的使用。通过实例解析原型如何为对象提供共享属性和方法,以及如何沿着原型链查找属性。同时,提供了相关编程题以加深理解。
摘要由CSDN通过智能技术生成

一、原型

1.1、什么是原型对象

  1. 原型对象的本质,就是一个普通的Object实例{}

  2. 每个函数都有一个prototype属性,该属性指向的是原型对象(显示原型对象

  3. 每个实例对象身上都有一个__proto__属性,该属性指向的也是原型对象(隐式原型对象

  4. 构造函数的显示原型 === 当前构造函数实例对象的隐式原型

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.showAge = function() {
    console.log(this.age)
  }
}
Person.prototype.showName = function() {
  console.log(this.name)
}

var person1 = new Person('WANG', 18);


console.log(person1)          // 隐式原型
console.log(Person.prototype) // 显示原型

在这里插入图片描述

1.2、原型对象的作用

给原型对象添加属性(一般是方法),这个函数的所有实例对象自动拥有原型中的属性(方法)

1.3、笔试题

function Fn() {
  this.test1 = function() {
    console.log('test1()')
  }
}

Fn.prototype.test2 = function() {
  console.log('test2()')
}

var fn = new Fn()

fn.test1()   
fn.test2()
console.log(fn.toString())
fn.test3()

结果:

test1()
test2()
[object Object]
Uncaught TypeError: fn.test3 is not a function at test.html:27(报错)

解析:

fn.test1()   // 1. 在实例本身找到 fn

fn.test2()   // 2. 在实例的原型上找到,fn.__proto__

console.log(fn.toString()) // 3. 在实例的 原型 的 原型Object找到 toString方法 fn.__proto__.__proto__

fn.test3()    // 4. 都找不到,报错

1.4、图解面试题

在这里插入图片描述

二、原型链

2.1、什么是原型链

js查找 对象的属性 过程:

  1. 先在自身找,如果自身找不到,就沿着 __proto__ 找原型对象

  2. 如果原型对象没有,继续沿着 __proto__,直到找到 Object的原型对象

  3. 如果还没有找到,返回undefined

那么,原型链就是:沿着__proto__查找的这条链 就是原型链

在这里插入图片描述

三、instanceof

  • 表达式:A instanceof B
  • 原理:如果 B 的显示原型对象 在 A对象的原型链上,返回true,否则返回 false
  • A.(多个__proto__) === B.prototype
function Foo() {}

var f1 = new Foo()

console.log(f1 instanceof Foo)  // true, 等同于下面
// console.log(f1.__proto__ === Foo.prototype)

console.log(f1 instanceof Object) // true, 等同于下面
// console.log(f1.__proto__.__proto__ === Object.prototype)

四、完整原型链图解

在这里插入图片描述

对应的编程题

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

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

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

五、笔试题

1. 第一道(附解析)

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, undefined, 2, 3

解析:

var A = function() {  // 1. 一个A的函数对象

}

A.prototype.n = 1  // 2. A的原型对象,分配地址例如:0x123, 内容为 {n:1}

var b = new A() // 3. A的实例化对象b,__proto__指向地址:0x123,内容为:{n:1}

A.prototype = { // 4. A的原型对象改变指针,指向新的地址:0x345,内容为:{n:2, m:3}
n: 2,
m: 3
}

var c = new A() // 5. A的实例化对象c, __proto__指向地址:0x345,内容为:{n: 2, m:3}

console.log(b.n, b.m, c.n, c.m)// 6. 那么b内容为{n:1} , c内容为:{n: 2, m:3}

2. 第二道(附解析)

var F = function(){}

Object.prototype.a = function(){
  console.log('a()')
}

Function.prototype.b = function(){
  console.log('b()')
}

var f = new F()
f.a() 
f.b()
F.a()
F.b()

答案:

f.a() // a()
f.b() // 报错,下面就不会运行了
F.a()
F.b()

解析:

var F = function(){} // 1. 第一个,作为函数对象, 第二个,所有的函数都是 Function 的实例对象

Object.prototype.a = function(){ // 2. Object的原型对象,有:a()
console.log('a()')
}

Function.prototype.b = function(){ // 3. Function的原型对象,有:b()
console.log('b()')
}

var f = new F() // 4. F作为函数对象的实例化对象f

// 5. f的原型链上,第一个__proto__是:F的原型对象,没有值
// 第二个 __proto__是:Object的原型对象,有a()
f.a() // 所以输出 a()
f.b() // 因为没有b,返回undefined,undefined不是函数,所以undefined()报错

// 6. F作为Function的实例对象,第一个__proto__是:Function的原型对象,有 b()
// 第二个__proto__是:Object的原型对象,有a()
F.a() // 所以输出 a() 
F.b() // 所以输出b()

所以,将报错注释掉,那么就输出 a()、(报错) 、a()、b()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值