new
new操作符用于生成一个构造函数的实例化对象,可以继承构造函数的所有对象和方法
调用new操作符会发生以下五件事情:
1、首先创建一个新的空对象
function myNew(fn,...agrs){
let obj = {}
}
2、 将这个对象的原型设置为构造函数的prototype对象、这样就能继承到fn里面的所有对象
function myNew(fn,...agrs){
let obj = {}
obj.__proto__ = fn.prototype
}
3、让构造函数的this指向这个新的对象:这样实例化对象的this就会指向构造函数
function myNew(fn,...args){
let obj = {}
obj.__proto__ = fn.prototype
fn.call(obj,...args)
}
4、返回这个新对象
function myNew(fn,...args){
let obj = {}
obj.__proto__ = fn.prototype
fn.call(obj,...args)
return obj
}
深拷贝、浅拷贝
// 需要先理解什么是堆类型和栈类型?
// 栈内存是保存固定大小的基本数据类型,即基础数据类型
Number Undefined Boolean Null String
// 堆内存即引用数据类型 保存的是内存的地址
Object Array Function
浅拷贝:一个新对象对已存在对象的对象属性的地址引用即浅拷贝
// Object.assign()方法
Object.assign(newObj,obj)
// 或直接赋值
let newObj = obj
深拷贝:本质是开辟一个新内存空间 把需要拷贝的对象取过来
// 通过转换成字符串再转成对象的形式赋值给新对象
// 弊端:函数,undefined,则序列化的结果会把函数, undefined丢失
let newObj = JSON.parse(JSON.stringify(Obj))
// 手写递归深拷贝实现
function MyClone(obj){
// 先判断传进来的值是不是引用类型 如不是直接返回
if(!obj instanceof Object){
return obj
}
// 创建一个新对象
let newObj = {}
// 递归把obj的每一个对象赋值给newObj
for(key in obj){
newObj[key] = MyClone(obj[key])
}
// 返回拷贝好的新对象
return newObj
}
call、apply、bind
他们都是改变了函数的this指向、call、apply改变后会立即执行函数、bind需要再次调用
// 如果想函数直接调用需要把函数挂载到Function原型上面
Function.prototype.MyCall = function(){}
Function.prototype.MyApply = function(){}
Function.prototype.MyBind = function(){}
// 手写call
Function.prototype.MyCall = function (fn,...args){
// 调用时先判断有没有传对象进来 没有就给window
fn = fn || window
// 因为this指向该函数调用者 所有在fn上面新建一个对象保存当前this
fn._this = this
// 调用该this并返回
let resulte = fn._this(args)
return resulte
}
// 手写apply(只有args是不是数组的却别)
Function.prototype.MyApply = function (fn,...args){
// 调用时先判断有没有传对象进来 没有就给window
fn = fn || window
// 因为this指向该函数调用者 所有在fn上面新建一个对象保存当前this
fn._this = this
// 调用该this并返回
args = args || []
let resulte = fn._this(...args)
return resulte
}
// 手写 bind(因为需要再次调用 所以里面必定再返回一个函数)
Function.prototype.MyBind = function (fn,...args1){
// 调用时先判断有没有传对象进来 没有就给window
fn = fn || window
// 返回的函数里面也要接收一个参数
return function(...args1){
// 因为this指向该函数调用者 所有在fn上面新建一个对象保存当前this
fn._this = this
// 合并两个参数
let argsAll = [...args1,...args2]
// 调用该this并返回
let resulte = fn._this(...argsAll)
return resulte
}
}