当前位置:网站首页>原型与原型链
原型与原型链
2022-08-08 06:21:00 【Youser511】
构造函数
内置构造函数
自定义构造函数
构造函数中的属性和方法 称为成员,成员可以添加
function Star(name,age){
this.name = name;
this.age = age;
this.sing = function(){
console.log("我会唱歌");
}
}
// 通过new 创建对象 ---实例化对象
var s = new Star('小小',12);
1:实例成员就是构造函数内部通过this添加的成员 name ,age ,sing就是实例成员
实例成员只能通过实例化对象来访问,不可以通过构造函数来访问实例成员
console.log(s.name);// 小小
console.log(Star.name);//Star
2:静态成员 在构造函数本身上添加的成员 sex就是静态成员
Star.sex = "男";
静态成员只能通过构造函数来访问,不能通过实例对象来访问
console.log(Star.sex)//男
console.log(s.sex) //undefined
构造函数存在问题
构造函数方法,存在浪费内存的问题。
我们希望所有的对象使用同一个函数,这样节省内存,如何使用同一个函数呢?
原型
js规定,每一个构造函数都有一个prototype属性,指向另一个对象。
这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有
我们可以把哪些不变的方法,定义在prototype对象上,这样所有对象的实例就可以共享这些方法
function Star(name,age){
this.name = name;
this.age = age;
}
// 往构造函数的原型对象中添加方法
Star.prototype.sing = function(){
console.log("我会唱歌");
}
var s1 = new Star('张三',12);
var s2 = new Star('李四',23);
console.log(s1.sing === s2.sing); //true
s1.sing(); //s1实例调用构造函数原型的方法
s2.sing(); //s2实例调用构造函数原型的方法
- 一般情况下,公共的属性定义到构造函数里,公共的方法我们放到原型对象上
- 构造函数中定义的方法会浪费内存空间 使用原型 解决 所有的对象共有同一个函数
- 原型解决的问题是,节省内存空间
每一个构造函数都有一个属性prototype
构造函数.prototype指向构造函数的原型;构造函数.prototype就是一个对象,这个对象的属性和方法 ,都会被构造函数所拥有
所以构造函数的实例对象 可以访问构造函数的原型对象中的成员
对象的原型
- 对象都会有一个属性 proto 指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在;
- proto 对象原型和原型对象 prototype 是等价的
- proto 对象原型的意义在于为对象的查找机制提供了一个方向,但是它是一个非标准属性,因此在实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype
function Star(name,age){
this.name = name;
this.age = age;
//this.sing = function(){
//console.log(123)
//}
}
// 给构造函数原型添加成员
Star.prototype.sing = function(){
console.log("唱歌");
}
var s1 = new Star("张三",12);
var s2 = new Star('李四',13);
s1.sing(); //实例对象可以访问原型对象成员
// 对象身上系统自己添加一个__proto__指向我们构造函数的原型对象 prototype
console.log(s1)
console.log(s1.__proto__ === Star.prototype); //true

实例对象调用方法 查找规则:
首先先看 s1对象上是否有sing方法 如果有就执行对象上的sing,如果没有就去它的构造函数的原型上查找。
总结:
- 原型就是原型对象
构造函数.prototype就是原型实例对象.__proto__===构造函数.prototype
原型链
每一个实例对象有__proto__属性,指向的是构造函数的原型对象,构造函数的原型对象也是一个对象,也有__proto__属性,这样一层一层往上找就形成了原型链

function Star(name,age){
this.name = name;
this.age = age;
}
// 原型对象
Star.prototype.sing = function(){
console.log("我会跳舞");
}
// 实例化对象
var s = new Star('张三',12);
1.只要是对象就有 __proto__ 指向原型对象
console.log(Star.prototype === s.__proto__);//true
2.我们Star原型对象的__proto__ 指向的是Object.prototype
// Star的原型对象 是 Object的实例化对象
console.log(Star.prototype.__proto__ === Object.prototype); //true
3.我们Object.prototype原型对象的__proto__指向为null
console.log(Object.prototype.__proto__); //null
constructor构造函数
对象 proto 和构造函数prototype 里都有一个属性 constructor
constructor 我们称为构造函数,因为他指回构造函数本身
constructor 主要用来 记录对象引用于哪个构造函数
function Star(name,age){
this.name = name;
this.age = age;
}
Star.prototype.sing = function(){
console.log("我会跳舞")
}
var s = new Star('李四',45);
console.log(s.constructor)
/* ƒ Star(name,age){ this.name = name; this.age = age; } */
constructor 指向的是 自身的构造函数;
我们修改了原来的原型对象,给原型对象赋值的是一个对象:
function Star(name,age){
this.name = name;
this.age = age;
}
Star.prototype = {
// 需要我们手动的给constructor 指回原来的构造函数
// constructor:Star,
sing:function(){
console.log("我会跳舞")
},
movie:function(){
console.log("我爱看电影")
}
}
var s = new Star('李四',45);
console.log(s.constructor)
// ƒ Object() { [native code] }
都说要手动指回原来的构造函数,但我不知道为什么,或这个说 记录下对象引用于哪个构造函数 有什么用,,我就只能先记下,日后知道的时候再回来补充。。
原型链成员查找规则
- 当访问一个对象的属性或者方法时,首先查找这个对象自身有没有该属性
- 如果没有就查找它的原型(也就是__proto__指向的prototype原型对象)
- 如果还没有查找到就查找原型对象的原型 (Object的原型对象)
- 类推 一直找到Object位置 null
function Star(name,age){
this.name = name;
this.age = age;
}
Star.prototype.sing = function(){
console.log("我回唱歌");
}
Star.prototype.sex = "女";
var s = new Star('小小',34);
console.log(s.sex); //女
console.log(Object.prototype);
console.log(s);
console.log(Star.prototype);
console.log(s.toString());//[object Object]
原型对象中this的指向
构造函数中的this 和 原型对象中的this 都指向我们new出来的实例对象
function Star(name,age){
this.name = name;
this.age = age;
}
var that;
Star.prototype.sing = function(){
console.log("我会唱歌");
that = this;
}
var s = new Star('小妞',12);
s.sing();
console.log(that === s); //true
通过原型为数组扩展内置方法
数组.push
数组.splice
数组.shift
…
都是定义在
Array.prototype原型对象上的
// 为数组扩展内置方法
Array.prototype.sum = function(){
// this 指向arr
var sum = 0;
for(var i = 0; i <this.length;i ++){
sum += this[i]
}
return sum
}
var arr = new Array(23,45,1,2,4,5,7)
// arr.push(23,45,1,2,4,5,7)
// console.log(arr)
console.log(arr.sum())
继承
call方法
call() 可以调用函数
call()可以修改this的指向,使用call()的时候,参数1是修改后的this指向,参数2,参数3 使用逗号隔开
构造函数继承:
只能继承父类的实例属性和方法 ,不能继承 原型属性或者方法
// 父构造函数
function Parentl(){
this.name = 'parentl'
}
Parentl.prototype.getName = function(){
return this.name
}
// 子构造函数
function Child(){
// this指向子构造函数的对象实例
Parentl.call(this); //c
this.type = "child"
}
var c = new Child();
console.log(c); //继承了Parentl的name属性
console.log(c.getName())//报错
// 父类原型对象中一旦存在父类之前自己定义的方法,那么子类将无法继承这些方法
借用原型对象继承方法
// 1:父构造函数
function Parentl(name,age){
// this指向父构造函数的对象实例
this.name = name;
this.age = age;
}
Parentl.prototype.money = function(){
console.log(1000000);
}
// 子构造函数
function Child(name,age,score){
// this指向子构造函数的对象实例
Parentl.call(this,name,age); //c
this.score = score;
}
Child.prototype = new Parentl()
// 利用对象的形式修改了原型对象,手动设置constructor
Child.prototype.constructor = Child
Child.prototype.exam = function(){
console.log("要考试了")
}
var c = new Child('小明',20,98);
console.log(c);
console.log(c.money);
console.log(Parentl.prototype);
console.log(Child.prototype.constructor)
边栏推荐
猜你喜欢

MySQL database

Disadvantages of flex layout

pycharm 自定义标识符颜色

Neural network to solve what problem, neural network results is not stable

Completed - desktop interactive wizard design based on facial expressions (share the results, attach the data set of facial expressions and the yolov5 model trained by yourself and the interactive int

Docker安装nacos2.0并指定mysql,安装sentinel

Graphical LeetCode - 636. Exclusive Time of Functions (Difficulty: Moderate)

convolutional neural network image recognition, convolutional neural network image processing

torch.gather() usage interpretation

cnn convolutional neural network backpropagation, convolutional neural network dimension change
随机推荐
独立成分分析ICA/FastICA
Graphical LeetCode - 636. Exclusive Time of Functions (Difficulty: Moderate)
整数分块例题
七千字带你了解封装等机制
李沐老师 PyTorch版——线性回归 + softmax回归的简洁实现(3)
PostgreSQL中想新建一个用户,让他仅能访问指定数据表,不能通过客户端工具看到表结构和函数内容,是否有方案可解决?
navicat15 连接Oracle数据库 报错ORA-28547: connection to server failed, probable Oracle Net admin error的解决方案
使用XGboost进行分类,判断该患者是否患有糖尿病
scikit-learn随机数据生成实例
2022秋春招/提前批面经分享总结(字节、腾讯、阿里)
C语言中求两数最大公约数的三种方法
LLVM系列第二十九章:写一个简单的常量加法“消除”工具(Pass)
YoloV4训练自己的数据集(五)
Horizontal version of the generated image uniapp H5 signature
4G/5G频谱资源协同关键技术
Summary of digital IC design written test questions (4): some basic knowledge points
docker安装Mysql和其数据持久化
Test and Debug
500道Golang 常⻅⾯试题⽬解析
YoloV4训练自己的数据集(三)