JavaScript高级04:函数高级之原型与原型链

一.原型

01显式原型(prototype)
显式原型图
解释:每个函数都有一个显式原型属性(prototype),它们各自的显式原型属性指向一个空的显式原型对象

区分
执行函数定义:函数体不执行,只创建了一个函数对象(本质就是定义函数)
执行函数():执行函数体

当你执行一个函数的定义时,浏览器会自动执行如下语句:

this.prototype = {}//this指的是你定义的那个函数对象(函数自身也是一个对象)

关于实例的解释:
01函数:你所定义的函数自身也是一个实例对象(是大写Function()的实例),不过我们一般称函数这个特殊的实例为类型
02通过new一个构造函数产生的实例对象,是类型的实例,这也是我们最常用的称呼

02隐式原型proto
当你创建一个实例对象时,浏览器会自动调用下列代码:

this.__proto__ = 构造函数名.prototype

上述操作在内存层面的解释为:构造函数将自己的显式原型属性prototype的值(是一个地址值,指向的是一个空的object实例对象)传给了你创建的那个实例对象的隐式原型属性__proto__所以,我们可以得到一个结论:
实例对象的隐式原型属性和其构造函数的显式原型属性指向的是同一个对象
这个结论是很关键的,这意味着,当你添加或者修改一个构造函数的prototype中的属性时,这个构造函数的实例对象也可以沿着原型链(后面提及)访问到,当然,这个属性也可以是一个方法。
下面,我们给定一段具体的代码,画出其代码图解加以解释:

function fun1() {
}
fun1.prototype.test = function(){
  console.log("test")
}
let f1 = new fun1()
  f1.test()

原型链内存图(简)

图片为本人手绘,虽然有点草率,但还是能说明问题滴

二.原型链

其实上面画的示例图中已经大致给出了原型链在内存中的分配管理问题,所谓原型链,我理解的是当你调用你创建的实例对象去访问一个属性或者调用一个方法时,该实例对象会优先访问自身的对象属性(方法)若自身找不到该属性(方法)则会沿着隐式原型属性__proto__进入下一个对象去寻找要找的属性(方法),若找到,则调用返回,若找不到,则继续访问这个对象的隐式原型属性__proto__,以此类推,如果直到访问到了object原型对象还找不到你要找的属性(方法),则停止查找(因为其隐式原型属性__proto__=null)返回undefined。

区分:

obj.test()//自身找不到的话会看原型链,若在原型链上找不到返回undefined
obj.test = //不看原型链,只是设置了obj对象自身的一个属性

补充instanceof:
A instanceof B
若返回true 则A是实例对象,B是构造函数
注意:只要B的prototype指向的是A隐式原型链上若干原型对象的其中某一个,就可以把A看作B的实例(A instanceof B返回true)

function fun1() {
}
fun1.prototype.name = "bob"
let f1 = new fun1()
console.log(f1.name)//bob
f1.name = "tom"
console.log(f1.name)//tom
console.log(f1 instanceof Object)//true

注:若改变一个构造函数的显式原型指向(构造函数.prototype = 新{ }),其改变之前的实例对象的__proto__指向不变,但改变后新声明的实例对象的__proto__指向会改变为你所定义的新prototype指向的对象

function fun1() {

}
fun1.prototype.name = "bob"
let f1 = new fun1()
console.log(f1.name)//bob
fun1.prototype = {
  name:"tom"
}
console.log(f1.name)//bob
let f2 = new fun1()
console.log(f2.name)//tom

作者留言:本文章主要用于交流学习,若有内容错误或补充欢迎各位留言或者私信,我会本着积极学习的态度认真考虑补充各位的意见。
原创文章,侵权必究
From:指尖旋律QAQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您提供一些 JS 高级原型原型链的练习题,希望对您有所帮助。 1. 创建一个构造函数 Person,它有属性 name 和 age。创建一个对象 john,它的 name 是 "John",age 是 30。使用 Person 的原型对象添加一个方法 sayHello,它会在控制台输出 "Hello, my name is {name}!"。 ```javascript function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}!`); }; const john = new Person("John", 30); john.sayHello(); ``` 2. 创建一个构造函数 Animal,它有属性 name 和 type。创建一个对象 cat,它的 name 是 "Whiskers",type 是 "Cat"。使用 Object.create() 方法创建一个对象 dog,它的 name 是 "Fido",type 是 "Dog"。使用 Animal 的原型对象添加一个方法 sayType,它会在控制台输出 "{name} is a {type}."。 ```javascript function Animal(name, type) { this.name = name; this.type = type; } Animal.prototype.sayType = function() { console.log(`${this.name} is a ${this.type}.`); }; const cat = new Animal("Whiskers", "Cat"); const dog = Object.create(Animal.prototype, { name: { value: "Fido", writable: true, enumerable: true, configurable: true }, type: { value: "Dog", writable: true, enumerable: true, configurable: true } }); cat.sayType(); // Whiskers is a Cat. dog.sayType(); // Fido is a Dog. ``` 3. 创建一个构造函数 Shape,它有属性 color 和 name。创建一个对象 circle,它的 color 是 "red",name 是 "Circle"。创建一个对象 square,它的 color 是 "green",name 是 "Square"。使用 Shape 的原型对象添加一个方法 describe,它会在控制台输出 "This is a {color} {name}."。 ```javascript function Shape(color, name) { this.color = color; this.name = name; } Shape.prototype.describe = function() { console.log(`This is a ${this.color} ${this.name}.`); }; const circle = new Shape("red", "Circle"); const square = new Shape("green", "Square"); circle.describe(); // This is a red Circle. square.describe(); // This is a green Square. ``` 希望这些练习题能够帮助您巩固 JS 高级原型原型链的知识。如果您有任何问题或需要进一步的帮助,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

指尖旋律QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值