原型和原型链
原型
定义: 每一个函数天生自带一个属性叫做 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类型,不可枚举和原型链不能复制 浅复制