当前位置: 首页 > news >正文

9.5 面向对象-原型和原型链

什么是原型对象

function Student(name,adderss){// 构造属性this.name = name;this.age = age;this.address = address;// 构造方法this.say = function(){console.log('我是',this.name,'我来自'+this.address);}
}
var one = new Student('Jack',19,'郑州');
var two = new Student('Rose',15,'郑州');

总结:new一个实例话对象经历的四个阶段:

  1. 创建一个空的实例化对象

  2. 让构造函数中的this指向空的实例化对象

  3. 执行(调用)构造函数,从而创建实例化对象自身的属性和方法

  4. 返回实例化对象

原型对象prototype(理解)

function Person(name,age){this.name=name;this.age=age;this.say=function(){alert('我偷偷告诉你:'+this.name+"今年"+this.age+'岁了');}
}
var p1 = new Person('jack',20); // 作为构造函数调用
p1.say();
var p2 = new Person('Rose',26); // 作为构造函数调用
p1.say();

![[1280X1280 (6).PNG]]
总结:
原型对象:所有的构造函数在初始化时,都会自动生成一个特殊的实例话对象,构造函数的prototype属性指向该对象,该对象称为原型对象,或prototype对象

proto__对象:所有构造函数new出来的实例话对象,都有一个__proto__属性,该属性指向构造函数的原型对象,原型对象也有自己的__proto__属性,指向上一级构造函数的原型对象,proto__会一直找到Object的原型对象,object原型对象的__proto__指向null

原型链:由一系列__proto__属性,串联起来的原型对象,称为原型链

原型链的意义:实例化对象在访问属性和方法时,会先访问自身的属性和方法,如果自身不存在对应的属性和方法,则会自动通过__proto__属性在整个原型链上查找,只要找到对应的属性和方法,就能正确执行,如果原型链上没找到,则报错

__proto__会一直找到Object

注意:构造函数本身是Function对象new出来的实例话对象,所以构造函数Studnet也有 proto ,指向Function的原型对象(Function.protytype); 而Function.protytype的 proto **指向Object.prototype **但是:**student这个构造函数new出来的实例话对象的原型链上并没有Function.prototype

面试题:什么是原型对象?什么是原型链?

原型对象:所有的构造函数在初始化的时候,会自动生成一个特殊的实例化对象,构造函数的prototype属性会指向该对象,该对象就被称为原型对象,或者prototype对象
什么是原型链:由一些列__proto__对象,串联起来的原型对象,称为原型链

![[ad19e6ab-274f-4874-8f84-985f3634ad82.png]]

原型链案例

给数组对象添加一个新的方法,实现去重
1)构建一个新的数组存放结果

2)for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比

3)若结果数组中没有该元素,则存到结果数组中

Array.prototype.unique1 = function () {var res = [this[0]]; // 结果数组for (var i = 1; i < this.length; i++) {var repeat = false;for (var j = 0; j < res.length; j++) {if (this[i] == res[j]) {repeat = true;break;}}if (!repeat) {res.push(this[i]);}}return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0];
alert(arr.unique1());

程序题

for(var i = 0; i < 10; i++){//回调函数: 做为参数传入的函数称为回调函数setTimeout(function(){   //异步/延时操作console.log(i,'inner');},0);
}
console.log(i,'outer');

程序题

var x = 1234;
function test(){var x = 4567;console.log(this.x);  
}
test();
var testObj = new test();
var o = {};
o.x = 5678;
o.m = test;
o.m();

程序题

// 函数声明优先: 如果普通变量和函数名冲突,最终变量中存储的是函数
function Foo() {getName = function () {console.log(1);};return this;
}
Foo.a=0; //静态变量
Foo.getName = function () { // 静态方法//在构造函数上添加一个属性(因为函数也是对象)console.log(2); 
};
Foo.prototype.getName = function () { console.log(3); };
var getName = function () { console.log(4); };
function getName() {console.log(5); 
}
Foo.getName();
getName();
Foo().getName();
getName();
new Foo().getName();

解析:静态属性不能被实例对象调用,即通过以new 操作符实例化后的对象调用,如上例中的a调用,只能通过类名调用,即Foo调用.也就是挂载在函数自身上的方法 本质上静态方法是定义在类上的,可以通过类名来访问,在静态方法中 this 是指向类本身,类实际上就是一个函数,一个构造器。

程序分析题

// 自定义对象的实例化对象,原型链上没有Function.prototype
// 而所有的函数实例化对象,_proto_属性指向Function.prototype, 而Function.prototype的_proto_属性指向Object.prototype
var F = function(){};
Object.prototype.a = function(){ console.log("hello")};
Function.prototype.b = function(){console.log("word")};
var f = new F();
var f1 = f.a;
f1();  
var f2 = f.b;
// f2();  
var f3 = F.a;
f3(); 
var f4 = F.b;
f4();

程序分析题

function A(){};
function B(a){ this.a = a};
function C(a){ if(a){this.a = a;}}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log( new A().a);  
console.log( new B().a);  
console.log( new C(2).a);

程序分析题

function Cat(name,color){this.name = name;this.color = color;
}
Cat.say = function(){console.log(this.name1);
}
Cat.name1 = "kmf";
var cat1 = new Cat('cat1','white');
cat1.say(); 
Cat.say(); 
// 1. 执行new的时候this指什么
// 2.cat1.say()输出什么?
// 3.Cat.say() 输出什么?

案例:使用构造函数+原型实现气泡效果
![[a401d4a9-04ce-4106-a8ae-8e3a9a799a07.png]]

JS的垃圾回收(GC)机制

程序运行过程中会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢。所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾。 当一个对象没有任何的变量或属性对它进行引用时,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,所以这种垃圾必须进行清理。 上面这句话,也可以这样理解:如果堆内存中的对象,没有任何变量指向它时,这个堆内存里的对象就会成为垃圾。 JS拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁。我们不需要也不能进行垃圾回收的操作。我们仅仅需要做的是:如果你不再使用该对象,那么,将改对象的引用设置为 null 即可。

一道题理解原型和原型链

Object.prototype是一个对象,用于表示Object的原型对象 几乎所有的JS对象都是Object的实例

  1. prototype原型对象:是函数才有的属性

  2. 函数的__proto__都指向Function.prototype

  3. __proto__内部原型,是对象才有的属性

  4. 对象由函数(构造器)生成

实例对象的__proto__属性

指向构造函数的prototype属性 即:__proto__表示的是,实例与(构造函数的原型)之间的关系

var fn = function(){this.f = "fn"
}
Object.prototype.a = function(){console.log('aaa')
}
Function.prototype.b = function(){console.log('bbb')
}
var f = new fn();
f.a() // 有没有a()
fn.a() // 有没有a()
fn.b() // 有没有a()
// console.log(f); 实例对象
// console.log(f.__proto__);
// console.log(f.__proto__.__proto__);
// console.log(Object.prototype);
// console.log(Object.prototype == f.__proto__.__proto__);
// console.log(f.__proto__.__proto__.a);

![[83689ba9-6c5d-4edf-a187-48872a0fcb55.png]]

http://www.xdnf.cn/news/1470331.html

相关文章:

  • 【Linux】Linux 的 cp -a 命令的作用
  • 2025高教社数学建模国赛B题 - 碳化硅外延层厚度的确定(完整参考论文)
  • Overleaf教程+Latex教程
  • Anaconda下载安装及详细配置的保姆级教程【Windows系统】
  • excel里面店铺这一列的数据结构是2C【uniteasone17】这种,我想只保留前面的2C部分,后面的【uniteasone17】不要
  • MySQL 8.0.36 主从复制完整实验
  • S32K3平台ADC 应用说明
  • 无人机RTK模块技术要点与难点
  • GEO排名优化:迈向个性化与语义化搜索时代的智能策略
  • VMwaer虚拟机安装完Centos后无法联网问题
  • SQL时间过滤神器:DATE_SUB+between实战指南,告别硬编码日期!
  • React 组件基础与事件处理
  • 04 - 【HTML】- 常用标签(下篇)
  • Windows环境下实现GitLab与Gitee仓库代码提交隔离
  • 今天一天三面,明天加油DW!!!
  • Linux文件描述符详解
  • baml:为提示工程注入工程化能力的Rust类型安全AI框架详解
  • 【完整源码+数据集+部署教程】广告牌实例分割系统源码和数据集:改进yolo11-dysample
  • MySQL数据库备份攻略:从Docker到本地部署
  • JAiRouter 0.7.0 发布:一键开启 OpenTelemetry 分布式追踪,链路性能全掌握
  • 环境搭建与你的第一个 Next.js 应用
  • 嵌入式单片机---串口通信及相关通信技术
  • PPIO上线kimi-k2-0905,编码能力大幅提升
  • 阿里云ESA 没有数据发送到SLS的解决
  • Linux调试命令速查:Java/微服务必备
  • 代码版本控制
  • C++ 异常
  • android嵌入式开发入门
  • GD32入门到实战34--ARM启动流程
  • 大模型——剪枝、量化、蒸馏、二值化