对于原型,原型链和对象复制的理解

本文详细介绍了JavaScript中的原型和原型链概念,包括每个函数和对象的prototype属性以及__proto__指针。讨论了内置构造函数如Object和Array,以及如何通过扩展构造函数的prototype为所有实例添加方法。此外,还阐述了原型链的作用,即对象访问机制,解释了变量和对象成员的查找过程。最后,提到了四种对象复制方法的优缺点,如Object.assign、JSON.parse与JSON.stringify、解构赋值以及深复制的进阶实现。

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

原型和原型链

原型

定义: 每一个函数天生自带一个属性叫做 prototype, 是一个对象数据类型
定义: 每一个对象天生自带一个属性叫做 __ proto __, 指向所属构造函数的 prototype
什么是原型: 函数天生自带的 prototype 属性叫做原型
原型的作用: 为了添加一些内容, 给函数的每一个实例使用
内置构造函数
+ Object, 是一个内置构造函数
+ JS 的语法里面一定有人定义过一个函数 function Object() {}
+ Array, 是一个内置构造函数
+ JS 的语法里面一定有人定义过一个函数 function Array() {}

    function Person(name) {
      this.name = name
    }
    // 我在向原型上添加一个方法
    Person.prototype.sayHi = function () {}
    const p1 = new Person('Jack')
    // 创建了一个数组, 使用 Array 构造函数创建了一个实例
    // 我想自己扩展一个数组常用方法, 写在什么位置 ?
    // 需要所有的数组都可以使用
    // 写在 Array.prototype 上就可以达到给每一个数组使用
    Array.prototype.myFn = function () {
      console.log('我是自己扩展的一个数组常用方法')
      // 自己扩展的方法, 因为将来一定是给实例进行调用
      // 这个函数内部的 this 就是构造函数的实例
      console.log(this)
    }

原型链

任何一个数据类型, 都有自己所属的构造函数, 如果不知道属于谁, 那么就是 Object 的实例
=> 任何一个 数组, constructor都是 Array 的实例
=> 任何一个 时间, constructor都是 Date 的实例
=> 任何一个 正则, constructor都是 RegExp 的实例
=> 任何一个 函数, constructor都是 Function 的实例
=> 任何一个 对象, constructor都是 Object 的实例
=> 任何一个 布尔, constructor都是 Boolean 的实例
=> …
=> 当发现一些不知道是谁的实例的对象, 那么constructor就是 Object 的实例

反射机制 通过对象反射它的类型,根据这个类型创建相同类型的对象

在这里有个利用反射机制和prototype实现对象的深复制和继承的进阶,参考链接博客
javaScript中的反射机制

原型链:
1. Object.prototype 是 JS 的顶级原型
2. Function 是 JS 的顶级函数
+ 定义: 按照 proto 串联起来的对象链状结构叫做原型链
+ 作用: 对象访问机制(对象访问自己成员的方式)

变量访问机制
+ 指的是访问变量的值
+ 当你需要访问一个变量的值的时候
+ 先在自己作用域内查找, 有就直接使用, 停止查找
+ 没有就去上一级作用域查找
+ 以此类推, 直到 全局作用域(window) 上都没有
+ 就报错, xxx is not defined

对象访问机制
指的是访问对象成员
当你需要访问一个对象的成员的时候
会首先在对象自己身上查找, 有就直接使用, 停止查找
如果没有, 就会自动去 proto 上查找(按照原型链查找上一级)
如果还没有, 就会再去 proto 上查找(按照原型链再上一级)
直到 Object.prototype(顶级原型) 都没有, 就返回 undefined

原型链图解:
在这里插入图片描述

关于对象复制的4种方法

//Objcet.assign();  复制对象 和原来对象之间没有引用关系  可以复制多个
var o={a:1};
var o1={b:2};
var o2={c:3};
var o3={d:4};
var c=Symbol();
//Object assign(目标对象,要复制的对象1,要复制的对象2)
var o2=Object.assign({},o);
var obj={};
Object.assign(obj,o,o1,o2,o3);  //会覆盖  并且仅复制自身的属性和方法,原型链上的是属性和方法不复制

//1.对象遍历复制
//for(var prop in obj){  
//不可枚举属性不能复制  不可遍历  symbol虽然不可枚举但是可以复制  浅复制
	//console.log(prop)
//}
console.log(obj);  
var a=3;
var b=Object.assign(0,a);  
// 非引用型变量没有对象属性,Object.assign无效
console.log(b);

//2.JSON.parse(JSON.stringfiy(obj)) 转换复制
o1=JSON.parse(JSON.stringfiy(o)) 
//修改了原引用关系  仅能复制字符属性,Symbol,不可枚举,原型链,函数和其他类型不能复制,深复制

//3.{,,,,}  解构赋值复制法
o1={....o};   
//修改引用关系 Symbol和函数都能复制, 不可枚举和原型链不能复制  浅复制


//4.Object.assign()  对象赋值法
//不修改引用关系,可以复制属性,方法,Symbol类型,不可枚举和原型链不能复制 浅复制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

MaxLoongLvs

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

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

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

打赏作者

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

抵扣说明:

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

余额充值